Kaydolun ve 100 ücretsiz kontrol almak için destekle iletişime geçin.Ücretsiz kaydol
Yanıt Sabitleri ile Çevrimdışı Carrier Lookup Entegrasyon Testi konulu CarrierLookup iş akışı görseli
Bu CarrierLookup makalesinde ele alınan iş akışına görsel bir genel bakış.

Bir CarrierLookup tüketicisinin ağa erişmesine izin vermeden önce taşıma katmanını enjekte edin ve açık sentetik yanıt sabitlerini test edin.

Carrier lookup API mock testleri, HTTP taşıma katmanını değiştirmeli, kazara ağ erişimini engellemeli ve uygulamanızın belgelenmiş her sonucu nasıl işlediğini doğrulamalıdır. Sentetik sabitler, telefon numarası göndermeden veya bakiye harcamadan tüketici mantığını test etmenizi sağlar.

Test bağlantısını HTTP isteğinden önce yerleştirin

Bir CRM içe aktarıcısı, "başarılı yol" testini geçebilir ancak yine de Belirlenemedi durumundaki bir numarayı geçersiz olarak etiketleyebilir. Ayrıca, arka ucu gerçek bir ücretli istek yaparken sahte bir tarayıcı testini de geçebilir. Test bağlantınızı, giden HTTP değişimini gerçekleştiren arka uç fonksiyonuna yerleştirin.

Tüketici, gerçek bir istemciyi dahili olarak keşfetmek yerine bir taşıma bağımlılığını kabul etmelidir. Enjekte edilen test taşıyıcısı, hedeflenen yolu ve istek gövdesini alır, bunları doğrular ve sentetik bir zarf döndürür. Testte API anahtarı bulunmaz. Canlı kimlik bilgilerini CI işinin dışında tutun.

Bir güvenlik önlemi olarak ayrı bir ağ kısıtlaması kullanın. Uygun veriler döndüren bir mock, her giden çağrının engellendiğinin kanıtı değildir. Giden trafiği CI konteyneri veya çalıştırıcı sınırında reddedin ve ağ erişimi denemelerinde işi başarısız kılın. Dil düzeyindeki bir koruma, yaygın hataları yakalamaya yardımcı olur ancak alt süreçleri veya her ağ kütüphanesini kapsayamaz.

Sabitleri yazmadan önce sonuçları tanımlayın

Senkron operatör hizmetimiz service_type=carrier kullanır. Tekli yanıtlar; identifier, carrier, underlying_carrier, number_type, country_code, region ve city dahil olmak üzere düz data alanlarına sahiptir. data.extra.carrier okumak, uydurma bir şekli test eder.

Sabit Tüketici doğrulaması
Kod 0 ve tahsis alanları Orijinal tahsis değerlerini koruyun
Kod 0 ve tüm tahsis alanları boş Mevcut olmayan değerlerle tamamlanmış sorgulama
Kod 42200 Belirlenemedi; boş bir başarı oluşturmayın
exists=false içeren çoklu öğe Normal sonuç yok; numarayı bağlantısı kesilmiş olarak işaretlemeyin
Kod 42901 Meşgul dalı; başarılı CRM güncellemesi yok
Kod 50400 Zaman aşımı dalı; başarılı CRM güncellemesi yok

Operatör değerleri orijinal tahsisi tanımlar. Bunlar, CRM'de "mevcut ağ" olarak adlandırılan bir alanı doldurmamalıdır. Benzer şekilde, ne boş bir tahsis sonucu ne de exists=false durumu telefon geçerliliğini kanıtlar. Ayrı uygulama sonuç etiketleri kullanın, böylece sonraki bir raporlama sorgusu bu durumları yanlışlıkla birleştiremez.

Küçük bir sentetik sabit paketi çalıştırın

Aşağıdakileri carrier_consumer_test.py olarak kaydedin ve python3 carrier_consumer_test.py komutuyla çalıştırın. Python'un standart kütüphanesini kullanır. Örnek, sentetik tanımlayıcılar ve bilinçli olarak seçilmiş değerlerle minimal bir tüketici bağlantısıdır; CarrierLookup ile asla iletişim kurmaz. Sabit doğrulamalarını korurken, örnek client ve sınıflandırıcıyı kendi adaptörünüzle değiştirin.

import socket
import unittest
from unittest.mock import patch

FIELDS = ("carrier", "underlying_carrier", "number_type",
          "country_code", "region", "city")
A, B = "+12025550101", "+12025550102"  # Yalnızca sentetik test verisi.

def classify(envelope):
    code = envelope["code"]
    if code != 0:
        return {42200: "undetermined", 42901: "busy",
                50400: "timeout"}.get(code, "error")
    data = envelope["data"]
    if data["service_type"] != "carrier":
        raise ValueError("unexpected service")
    return "completed" if data["carrier"] else "completed_empty"

def client(transport, identifiers):
    multi = len(identifiers) > 1
    path = "/api/v1/batch-check" if multi else "/api/v1/check"
    body = {"service_type": "carrier"}
    body["identifiers" if multi else "identifier"] = (
        identifiers if multi else identifiers[0])
    return transport(path, body)

def completed(identifier, carrier=""):
    return {"code": 0, "msg": "synthetic fixture", "data": {
        "service_type": "carrier", "identifier": identifier,
        **dict.fromkeys(FIELDS, ""), "carrier": carrier}}

class ConsumerTests(unittest.TestCase):
    def setUp(self):
        self.guard = patch.object(
            socket.socket, "connect",
            side_effect=AssertionError("network forbidden"))
        self.guard.start()
        self.addCleanup(self.guard.stop)

    def test_single_flat_data_and_outcomes(self):
        for value, expected in [("Example Allocation", "completed"),
                                ("", "completed_empty")]:
            def fake(path, body):
                self.assertEqual(path, "/api/v1/check")
                self.assertEqual(body, {"service_type": "carrier",
                                        "identifier": A})
                return completed(A, value)
            result = client(fake, [A])
            self.assertNotIn("extra", result["data"])
            self.assertNotIn("registered", result["data"])
            self.assertEqual(classify(result), expected)

    def test_error_branches(self):
        for code, expected in [(42200, "undetermined"),
                               (42901, "busy"), (50400, "timeout")]:
            with self.subTest(code=code):
                result = client(lambda path, body: {
                    "code": code, "msg": "synthetic error",
                    "data": None}, [A])
                self.assertEqual(classify(result), expected)

    def test_multi_order_and_no_result(self):
        def fake(path, body):
            self.assertEqual(path, "/api/v1/batch-check")
            self.assertEqual(body, {"service_type": "carrier",
                                    "identifiers": [B, A]})
            return {"code": 0, "msg": "synthetic fixture", "data": {
                "service_type": "carrier", "total": 2,
                "succeeded": 1, "failed": 1, "results": [
                    {"identifier": B, "exists": True,
                     **dict.fromkeys(FIELDS, "")},
                    {"identifier": A, "exists": False}]}}
        data = client(fake, [B, A])["data"]
        rows = data["results"]
        self.assertEqual(data["service_type"], "carrier")
        self.assertEqual([r["identifier"] for r in rows], [B, A])
        self.assertEqual(len(rows), data["total"])
        outcomes = ["completed" if r["exists"] else "no_result"
                    for r in rows]
        self.assertEqual(outcomes, ["completed", "no_result"])
        self.assertNotIn("carrier", rows[1])

    def test_guard_rejects_an_escape(self):
        with socket.socket() as sock:
            with self.assertRaisesRegex(AssertionError, "network forbidden"):
                sock.connect(("127.0.0.1", 9))

if __name__ == "__main__":
    unittest.main()

Örnek, taşıma katmanından halihazırda çözülmüş zarflar döndürür. HTTP ayrıştırmasından ziyade istek oluşturma ve sonuç işlemeyi test eder. HTTP durumu, başlıklar ve hatalı JSON için sabitleri gerçek taşıma sınırınızda da tutun. Özellikle, 42901 yanıtı Retry-After içerir; bir yanıt başlığı sabiti, taşıyıcınızın bunu arayan taraf için koruduğunu doğrulamalıdır. Sonuç sınıflandırıcısına yeni bir yeniden deneme aralığını sabit olarak kodlamayın.

Soket koruması, kendi hata yolunu kasıtlı olarak test eder. Bu Python sürecinin soket bağlantı yöntemini engeller; ayrı CI çıkış kısıtlaması diğer yollar için gerekli kalmaya devam eder. Kazara yapılan bir ücretli çağrı, işi başarısız kılmalı, fark edilmeyen fazladan bir sabit haline gelmemelidir.

Çoklu sonuç doğrulamalarını sıralama hatalarına karşı duyarlı hale getirin

Çoklu sabit, B'yi A'dan önce gönderir. Bu önemlidir: alfabetik olarak sıralanmış tanımlayıcıları gönderen ve aynı sıralı yanıtı alan bir test, yanıtları sıralayan bir adaptörü gözden kaçırabilir. Döndürülen her tanımlayıcıyı giriş konumuyla eşleştirin ve toplam uzunluğu doğrulayın.

İlk çoklu öğe, boş tahsis değerleriyle tamamlanmış bir sonuç üretir. İkincisi exists=false değerine sahiptir ve operatör alanı içermez. Uygulama kayıtlarına eşleme yaparken bu farkı koruyun. Üretim adaptörünüz başarısız satırları düşürürse, sabit başarısız olmalıdır çünkü sonraki satırlar yanlış kişilere kayabilir.

Gerçek CRM eşleme fonksiyonuna bir doğrulama ekleyin: belirlenemeyen veya başarısız bir sorgulama, önceki tahsis gözlemini olduğu gibi bırakmalı veya politikanız uyarınca açıkça eski olarak işaretlemelidir. Kaydı "geçersiz numara" ile üzerine yazmamalıdır. Aynı test, mevcut konumu tahsis bölgesinden veya şehrinden türetmeyi reddetmelidir.

Senkron bir çoklu zaman aşımı, kısmi sonuçlar olmadan tüm isteği başarısız kılar. Tüm istek zaman aşımı dalını, başarısız bir öğe içeren başarılı bir zarftan ayrı olarak test edin. Bunlar, tüketiciye farklı girişlerdir.

Çevrimdışı güveni canlı doğrulamadan ayrı tutun

Bu testler, kodunuzun sabitlerle temsil edilen sözleşmeye nasıl yanıt verdiğini belirler. Mevcut sağlayıcı kullanılabilirliğini, ülke kabulünü, hesap izinlerini veya faturalandırmayı göstermezler. Üretilmiş bir sabit, canlı bir sağlayıcının belirli bir numara için belirli bir tahsis alanı döndüreceğini de kanıtlayamaz.

Sabit kaynağını testin yanında tutun: CarrierLookup API reference, gözden geçirme tarihi ve adaptörünüzün tükettiği alanlar. Belgelenmiş bir sözleşme değiştiğinde sabitleri güncelleyin, ardından eski uygulama verilerinin uyumlu bir okuma yoluna ihtiyaç duyup duymadığını inceleyin.

Entegrasyon doğrulaması gerektirdiğinde, onaylanmış giriş ve kendi bakiye bütçesini kullanarak ayrı olarak yetkilendirilmiş bir canlı duman testi çalıştırın. Olağan CI'yi bu çağrıya bağımlı hale getirmeyin. Test paketinizdeki bir canlı istemci içe aktarımını enjekte edilmiş bir taşıyıcıyla değiştirerek ve ağdan kaçma girişiminin hemen başarısız olduğunu doğrulayarak başlayın.

Daha Fazla Bilgi

İş akışınızdaki bir sonraki adıma uygun ürün bilgilerini seçin.

Kaynaklar