Teknik not · python / api / test
Python ile API yanıtlarını karşılaştırmak: eksik alan, null ve tür farkı
Küçük JSON yanıtlarında alan varlığını ve tür farklarını koruyan, tamamen çevrimdışı bir karşılaştırma örneği.
İki API yanıtını karşılaştırırken yalnız before == after sonucuna bakmak bazı ayrıntıları gizleyebilir. Alanın hiç bulunmaması, bulunup null olması ve değerinin tür değiştirmesi farklı olaylardır. Küçük bir karşılaştırma yardımcısının amacı, bu ayrımları inceleme sırasında görünür tutmaktır. Buradaki örnek ağ isteği göndermez; önceden hazırlanmış iki küçük sözlükle çalışır.
Alanın varlığını ayrıca kaydedin
Python'da JSON null, None olarak temsil edilir. Sözlükteki get() çağrısı da varsayılan olarak eksik anahtar için None döndürür. Bu yüzden yalnız get() sonuçlarını karşılaştırmak, eksik alan ile açıkça boş bırakılmış alanı birleştirir. Çözüm, her değerle birlikte present bilgisini taşımaktır. Python json belgesi, Python sözlük işlemleri
before = {}
after = {"owner": None}
left = {"present": "owner" in before, "value": before.get("owner")}
right = {"present": "owner" in after, "value": after.get("owner")}
# left: {"present": False, "value": None}
# right: {"present": True, "value": None}Anahtarların birleşimini kullanmak da önemlidir. Yalnız önceki yanıttaki alanları gezmek, sonradan eklenen alanları kaçırır. Paket içindeki semantic_diff, iki taraftaki alanları birlikte dolaşır ve farklı olanları önceki/sonraki değerleriyle raporlar.
Boolean ile sayıyı karıştırmayın
Python eşitliğinde False == 0 ve True == 1 doğrudur; bool, int türünün alt sınıfıdır. API sözleşmesinde ise bayrak ile sayı farklı anlam taşıyabilir. Örnekte kayıtlar json.dumps(..., sort_keys=True, allow_nan=False) ile gösterime çevrilerek karşılaştırılır. Böylece boolean/sayı ayrımı iç içe listelerde de görünür kalır. Sözlük anahtarlarının sırası sonucu etkilemez, listelerin sırası etkiler. Python bool açıklaması, json dönüştürme seçenekleri
Bu yöntem genel bir anlamsal eşitlik tanımı değildir. Örneğin 1 ile 1.0 farklı JSON gösterimleri üretir ve fark sayılır. Bu, örneğin bilinçli karşılaştırma tercihidir; her API sözleşmesinin zorunlu kuralı değildir. İç içe değişikliklerin konumu da yaprak düzeyinde verilmez; ilgili üst düzey alanın tamamı raporlanır.
Hangi alanları dışarıda bırakmalı?
Bu çalışma verisinde yalnız üst düzey request_id, teknik korelasyon alanı olduğu varsayımıyla dışarıda bırakılır. id, owner ve tenant korunur. Kendi yanıtınızda bir alanı yok saymadan önce gerekçesini belirleyin; aynı isim her uygulamada aynı anlama gelmez. İç içe bir nesnedeki request_id bu örnekte dışlanmaz.
Çalıştırılabilir sürüm yalnız metin anahtarlı sözlükleri, listeleri ve sonlu JSON değerlerini kabul eder. Metin olmayan anahtarlar, tuple gibi JSON dışı Python türleri ve NaN/sonsuzluk reddedilir. Küçük örnekler için ayrıca 32 derinlik ve girdi başına 10.000 düğüm sınırı vardır. Bunlar genel amaçlı, kötü niyetli büyük veri işleme güvencesi değildir.
Çevrimdışı deneyin
Örnek ve testleri kod paketini indirerek edinebilirsiniz. ZIP dosyasını açınca python-example klasörünü kullanın. Standart kütüphane dışında bağımlılık gerekmez:
cd python-example
python3 semantic_diff.py
python3 -m unittest -vTestler eksik/null, boolean/sayı, iç içe değer, liste sırası, dışlanan alan ve geçersiz girdi davranışlarını kapsar. unittest belgesi testlerin nasıl çalıştırıldığını açıklar. Çıktı bir inceleme yardımcısıdır; tek başına BOLA veya başka bir güvenlik açığının kanıtı sayılmaz. Sahiplik, paylaşım politikası ve kullanıcı bağlamı ayrıca değerlendirilmelidir.