Otomasyon QAKıdemli Otomasyon QA Mühendisi

Olay odaklı sunucuya göre mimariler için otomatik test stratejisi geliştirin, asenkron işlev koreografisini doğrulayın, soğuk başlangıç gecikmesi değişkenliğini telafi edin ve dağıtılmış durumsuz bileşenler arasında idempotent yürütme anlamlarını garanti edin.

Hintsage yapay zeka asistanı ile mülakatları geçin

Sorunun cevabı

Sorunun geçmişi

Monolitik ve kapsüllenmiş mikro hizmetlerden olay odaklı sunucusuz mimarilere geçiş, durumun dışsallaştırıldığı, yürütmenin geçici olduğu ve altyapının tamamen bulut sağlayıcıları tarafından yönetildiği bir paradigma getirdi. Geleneksel test yaklaşımları, sıcak bağlantılar ve tahmin edilebilir başlangıç süreleri ile kalıcı hizmetlere dayanıyordu ve bu, soğuk başlangıçlar yaşayan Lambda işlevlerine veya Azure İşlevlerine uyumlu değildi. Şirketler, bu yönetilen hizmetlere standart test kancaları olmadan, SNS, SQS veya EventBridge aracılığıyla işlevlerin tetiklendiği karmaşık koreografi modellerini doğrulamakta zorluk çekerken bu soru ortaya çıktı.

Sorun

Sunucusuz mimariler üç kritik test zorluğu sunar: deterministik olmayan soğuk başlangıç gecikmeleri (çalışma zamanı ve VPC yapılandırmasına bağlı olarak 100 ms'den 8 saniyeye kadar), durumsuz çağrılar için hata ayıklama amacıyla doğrudan süreç kontrolü eksikliği ve işlevlerin iletim sırası garantileri nedeniyle tekrar deneyebileceği durumlarda idempotansıyı doğrulamanın zorluğu. Ayrıca, LocalStack veya SAM CLI gibi yerel emülasyon araçları IAM izin sınırları ve ağ gecikmesi açısından bulut davranışından genellikle saparken, üretim bulutları üzerinde doğrudan test yapmak, paralel CI hatlarını çalıştırırken büyük maliyetler ve veri yalıtım riskleri yaratır.

Çözüm

Çözüm, şu unsurları içeren hibrit bir test piramidi gerektirir: (1) Saf iş mantığını doğrulamak için bellek içi olay sahte verileri ve bağımlılık enjekte ederek birim testleri; (2) Geçici "test-per-PR" bulut yığınlarını Terraform veya AWS CDK aracılığıyla kullanarak ortaya çıkaran entegrasyon testleri, burada işlevler geçici DynamoDB tabloları ve benzersiz mantıksal izolasyon anahtarlarıyla SQS kuyrukları üzerinde tetiklenir; (3) Tam entegrasyon olmadan üretici-tüketici uyumluluğunu sağlamak için Pact gibi araçlar kullanarak olay şemalarını doğrulayan sözleşme testleri. Soğuk başlangıçları yönetmek için sabit gecikmeler yerine üssel geri dönüş ile adaptif anket uygulayın ve idempotent tekrarları izlemek için olay meta verisine enjekte edilmiş ilişkilendirme kimliklerini kullanın. Yük testleri için, hassas yükleri anonimleştirerek üretim olay kalıplarını yakalayan trafik yeniden oynatma mekanizmalarını kullanın.

import pytest import boto3 from moto import mock_aws import time from uuid import uuid4 class ServerlessTestHarness: def __init__(self): self.correlation_id = str(uuid4()) self.retry_count = 0 def invoke_with_cold_start_compensation(self, function_arn, payload, max_wait=30): """Soğuk başlangıç gecikmesini sağlık kontrolü anketi ile yönet""" lambda_client = boto3.client('lambda') start_time = time.time() while time.time() - start_time < max_wait: try: response = lambda_client.invoke( FunctionName=function_arn, Payload=json.dumps(payload), InvocationType='RequestResponse' ) if response['StatusCode'] == 200: return response except lambda_client.exceptions.ResourceNotFoundException: time.sleep(2) # Altyapı sağlama için bekleyin continue raise TimeoutError(f"{function_arn} işlevi {max_wait}s içinde soğuk başlamayı başaramadı") def assert_idempotency(self, function_arn, event_payload): """Aynı olayı iki kez çağırarak idempotansıyı doğrulayın""" event_id = str(uuid4()) enriched_payload = {**event_payload, 'idempotency_key': event_id} # İlk çağrı result1 = self.invoke_with_cold_start_compensation(function_arn, enriched_payload) # Aynı anahtarla ikinci çağrı result2 = self.invoke_with_cold_start_compensation(function_arn, enriched_payload) # Yan etkilerin olmaması gerektiğini doğrulayın (örneğin, tekrar eden veritabanı kayıtları) assert self.get_side_effect_count(event_id) == 1, "İşlev idempotent değil" @pytest.fixture def ephemeral_serverless_stack(): with mock_aws(): # Geçici altyapıyı kurun dynamodb = boto3.resource('dynamodb', region_name='us-east-1') table = dynamodb.create_table( TableName=f'test-inventory-{uuid4()}', KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}], AttributeDefinitions=[{'AttributeName': 'id', 'AttributeType': 'S'}], BillingMode='PAY_PER_REQUEST' ) yield ServerlessTestHarness() # Moto bağlam yöneticisi aracılığıyla otomatik temizleme

Hayattan bir durum

Sorun bağlamı

Bir perakende şirketi, envanter yönetim sistemini AWS Lambda, DynamoDB Akışları ve SNS'ye geçirerek Black Friday trafik zirvelerini yönetmek için taşıdı. Dağıtımdan sonra, QA ekibi, Lambda tekrarları nedeniyle bazı envanter güncelleme olaylarının bazen tekrar eden stok rezervasyonları oluşturduğunu keşfetti, bu da DynamoDB kısıtlamalarından kaynaklanıyordu. Hızla yanıt veren sahte veriler kullanan mevcut test takımı bu yarış koşullarını asla yakalayamadı. CI pipeline'daki paralel test yürütmeleri, paylaşılan bir DynamoDB tablosunu kullandıkları için çarpışıyordu ve bu da rezervasyon sayımlarını doğrularken testlerin başarısız olmasına neden oluyordu.

Değerlendirilen çözümler

Seçenek A: Sadece LocalStack testi. Bu yaklaşım, tüm AWS hizmetlerini yerel olarak Docker konteynerleri kullanarak çalıştırıyordu. Bu, hızlı geri bildirim sağlasa da (artılar: bulut maliyeti yok, alt saniye yürütme, ağ gecikmesi yok) ve kolay paralelleşme sağlasa da, gerçek dünyadaki IAM izin sorunlarını tespit edemedi ve DynamoDB'nin gerçek nihai tutarlılığı ile farklı tutarlılık modelleri sergiledi. Takım, LocalStack'ın SNS uygulamasının gerçek hizmette bulunan mesaj sıralama garantilerinden yoksun olduğunu gösteren önceki olaylardan dolayı bunu reddetti.

Seçenek B: Paylaşılan kalıcı sahneleme ortamı. Tüm testler için uzun ömürlü bir AWS hesabı kullanarak. Bu, üretim gerçekliği sağladı (artılar: gerçek soğuk başlangıç davranışı, gerçek IAM politikaları) ancak ciddi darboğazlar ortaya çıkardı: veri çarpışmasını önlemek için testler sıralandı (eksi: 200 test için 45 dakikalık yürütme süresi), aylık 3000 dolar bulut maliyetleri oluştu ve geliştiricilerin eşzamanlı olarak manuel test yaparken "gürültücü komşu" etkilerinden muzdarip oldu.

Seçenek C: Geçici PR başına altyapı (Seçilen). Her bir çekme isteği, Terraform'u benzersiz kaynak adlandırması (örneğin, table-inventory-pr-1234) ile izole bir yığın oluşturma işlemini tetikler, izleme için enjekte edilen ilişkilendirme kimlikleri ile testleri yürütür ve ardından kaynakları yok eder. Bu, gerçekçilik ile yalıtım arasında bir denge sağladı (artılar: gerçek sunucusuz davranış, paralel yürütme, 0.50 $ birim başına maliyet) ve soğuk başlangıçları zarif bir şekilde yönetmek için adaptif anket kullanırken, terkedilmiş yığınların otomatik çöp toplaması için kaynak etiketlemeyi sağladı.

Uygulama ve sonuç

Takım, benzersiz yığın ön ekini ortam değişkenlerine enjekte eden özel bir pytest eklentisi geliştirdi ve bu sayede test kodu izole kaynakları hedef aldı. Lambda işlevlerinde, tekrarların aynı izleme kimliğini taşıdığını doğrulamak için AWS X-Ray kullandılar, idempotansıyı doğru şekilde etkinleştirdi. Anlık okumalar varsaymak yerine, üssel geri dönüş ile DynamoDB'yi sorgulayan "nihai tutarlı" doğrulama olarak uyguladılar ve test başarısızlıklarının %94'ünü ortadan kaldırdılar. Pipeline şimdi, üretim dağıtımından önce envanter aşımına neden olabilecek üç kritik idempotans hatasını yakalayarak 50 paralel işçi ile 8 dakikada tamamlanıyor.

Adayların sıkça unuttuğu noktalar

Üretim veritabanlarını kirletmeden veya kalıcı test verisi kalıntıları oluşturmadan idempotansıyı nasıl test ediyorsunuz?

Adaylar genellikle her test çağrısı için UUID rastgeleleştirmesi önermektedir, bu da aslında idempotansıyı doğrulamak yerine hataları maskeleyebilir. Doğru yaklaşım, test durumu isimlerinden türetilen belirleyici idempotans anahtarlarını (örneğin, hash(test_module + test_name + timestamp_rounded_to_hour)) kullanarak, daha sonra birden fazla çağrıdan sonra veritabanını sorgulamak ve tam olarak bir satır oluşturulduğunu doğrulamaktır. Ayrıca, işlevin tekrar edişte aynı yanıt yükünü döndürdüğünü (genellikle idempotans tokenına göre anahtarlanmış bir DynamoDB TTL tablosunda sonuçları önbelleğe alarak) doğrulamanız gerekiyor, sadece tekrar eden yan etkileri bastırmak yeterli değildir.

Soğuk başlangıç gecikmelerini yönetirken neden sabit uyku gecikmeleri başarısız olur ve sağlam alternatif nedir?

Birçok aday, "soğuk başlangıç için beklemek" amacıyla doğrulamalardan önce time.sleep(10) eklemeyi önerir, bu da sıcak çağrılar sırasında testleri %90 oranında yavaşlatırlar ve hala 15 saniyeyi aşan VPC soğuk başlangıçlarında başarısız olurlar. Mimaride çözüm, sağlık kontrolü uç noktaları uygulamak veya AWS Lambda Invoke API'sinin InvocationType: DryRun parametresini kullanarak IAM izinlerini doğrulamak (bu, yürütme bağlamını da ısıtır) yerleştirip ardından gerçek test yükü gönderilmeden önce kontrol yapmak şeklinde uygulanır. Entegrasyon testleri için, test olayınızın işlevinin gerçekten yükünüzü işleyip işlemediğini doğrulamak amacıyla, belirli bir ilişkilendirme kimliğini kontrol eden CloudWatch Log'ları anket eden bir adaptif döngü uygulanır.

SNS/SQS en az bir kez teslimatı sağlarken ve potansiyel olarak sıralı işlem yaparken olay sırasını nasıl doğruluyorsunuz?

Adaylar genellikle, sunucusuz işlevlerin toplama veya sıra numarası takibi uygulamasını göz önünde bulundurması gerektiğini kaçırır. Testte, olayların gönderildiği sırada işleneceğini varsayamazsınız. Doğrulama stratejisi, olay meta verisine monotonik olarak artan sıra numaralarının enjekte edilmesini gerektirir, ardından işlevin çıktı durumu ya: (a) en yüksek işlenmiş sıra numarasını yansıtmalıdır, eğer işlev durumlu ise koşullu yazmalarla (attribute_exists kontrolü DynamoDB'de), veya (b) sıralı olmayan olaylar reddedilmelidir/sonraki işlem için kuyruklanmalıdır. Testler ayrıca, olay B'nin olay A'dan sonra gönderilmesine rağmen önce geldiği durumu simüle etmek için SQS gecikme kuyruğuna veya Adım İşlevlerine başvurmalıdır, işlevin davranışını doğrulamak için.