Codeception ile WordPress Siteniz İçin Otomatik API Testi


Eklentilerimizi sattığımız WooCommerce sitemizde otomatik testler yapmak için Codeception'ı nasıl kullandığımız hakkında daha önce yazmıştım. Otomatik testler, WooCommerce, diğer eklentiler veya WordPress'in kendisini güncelledikten sonra ödeme işlemimizin hala çalıştığı konusunda bize gönül rahatlığı veriyor. Şirketimizin çok önemli bir parçasıdır.

Ancak, premium WordPress eklentileri satan bir şirket olarak, sitenin e-ticaret akışına dahil olmadığı için test edilmemiş büyük bir bölümü var. Eklenti lisans anahtarlarının etkinleştirilmesi ve devre dışı bırakılması, eklenti ziplerinin güncellemelerinin sağlanması ve müşteri destek sistemimize destek istekleri gönderilmesi için API'mizden bahsediyorum.

API, sitenin ve işimizin son derece önemli bir parçasıdır, ancak bir süredir herhangi bir test eklemeyi erteliyordum. Yakın zamana kadar, üzerinde bazı değişiklikler yapmam gerekiyordu ve gerilemeleri yakalamak için bir test kapsamı güvenlik ağım olduğunu öğrenene kadar kendimi onları yapmaya ikna edemedim.

Birim testleri yazmayı düşündüm, ancak kodu test edilebilir hale getirmek için zamanım olmayan büyük bir yeniden düzenleyiciye gireceğimi çabucak fark ettim. Sitenin geri kalanı için kabul testleri yaptıktan sonra, API için de aynısını yapmak mantıklı geldi.

Bu, Codeception ile nasıl çalışır? Bu otomatik tıklama ve benzeri şeyler için değil mi? Codeception'ın API testi yapmayı mümkün kılan oldukça şık bir REST modülüne sahip olduğu ortaya çıktı. Sizi kurulum, yazma ve testleri çalıştırma sürecinden geçirmeme izin verin.

Test Paketi Kurulumu

Codeception'ı önceki çalışmamdan zaten yükledim, bu yüzden burada ele almayacağım.

Codeception, özellikle API testleriniz için yeni bir test paketi yüklemenizi önerir ve bu, aşağıdaki komutu çalıştırmak kadar basittir:

 php vendor/bin/codecept generate:suite api

Takıma 'api' adını verdim ve Codeception şimdi yeni bir api.suite.yml yapılandırma dosyası ve takımın testleri için dizin de dahil olmak üzere gereken tüm dosyaları iskele edecek.

api.suite.yml dosyası, REST modülünü eklememiz ve site URL'mizle yapılandırmamız gereken yerdir. delciousbrains.com API'si WooCommerce tarafından desteklendiğinden, wc-api=delicious-brains sorgu dizesini WordPress site URL'sine ekledim, böylece testler varsayılan olarak API URL'sini kullanacak:

 actor: ApiTester modules: enabled: - REST config: REST: url: '%WP_URL%/?wc-api=delicious-brains' depends: PhpBrowser

Test Yazma

Ana site için testleri yazarken prosedürel 'Cept' formatını kullandım ama bu sefer dosyalarımı 'Cest' formatını kullanarak sınıflar olarak kurdum. 'Cept'ler prosedürel tarzda yazılırken 'Cest'ler sınıf formatında yazılır. Bu, belirli bir API uç noktasını temsil edecek bir test dosyasına sahip olabilmem ve bu uç noktanın çeşitli test senaryoları için farklı yöntemlere sahip olabilmem içindi.

Bir API testi yazmanın temelleri, API'ye bir istek göndermeyi ve yanıtı kontrol etmeyi içerir. REST modülü, GET, POST, PUT, DELETE ve PATCH istekleri gönderme yöntemlerinin yanı sıra istekten gelen yanıtı test etmek için çeşitli yöntemlere sahiptir.

Örneğin, bir uç noktanın JSON verileriyle 200 koduyla bir yanıt döndürdüğünü test edebilirsiniz:

 $I->sendGET('/posts', [ 'status' => 'pending' ]); $I->seeResponseCodeIs(200); $I->seeResponseIsJson();

Bir e-posta adresi gibi belirli verileri içerip içermediğini belirlemek için JSON yanıtını daha derine inebilirsiniz:

 $I->seeResponseContainsJson( array( 'success' => true ) );

Aktörün Özelleştirilmesi

Codeception, 'api' test paketini oluşturduğunda, varsayılan \Codeception\Actor sınıfını genişleten bir sınıfla birlikte bir ApiTester.php dosyası da dahil olmak üzere tests\_support dizininde bazı dosyalar oluşturdu. Burası, test senaryolarımızda yeniden kullanmak için yöntemler ekleyebileceğimiz yerdir.

Örneğin, WooCommerce API'miz, api.deliciousbrains.com/license/{key}/activate gibi fiillerle geleneksel URL yönlendirmesine sahip bir RESTful API değildir, bunun yerine verileri temel URL'ye iletmek için sorgu dizesi parametrelerini kullanır:

 https://deliciousbrains.com/?wc-api=delicious-brains&request=activate_licence&licence_key={key}

Daha önce belirtildiği gibi, api.suite.yml yapılandırmasında https://deliciousbrains.com/?wc-api=delicious-brains REST URL'si olarak ayarladım, bu nedenle sendGET ve sendPOST iletilen URL'yi özelleştirmem gerekiyor ekstra veri içeren yöntemler, ancak yeniden kullanılabilir bir şekilde, böylece test sırasında aynı uç nokta için birden çok kez arayabilirim. Bu yöntemi ApiTester.php dosyasına ekledim:

 public function sendRequest( $endpoint, $args = array(), $post_args = array() ) { $args = array_merge( array( 'request' => $endpoint ), $args ); $args = http_build_query( $args ); if ( ! empty( $post_args ) ) { $this->sendPOST( '&' . $args, $post_args ); return; } $this->sendGET( '&' . $args ); }

Bu, kendisine iletilen ekstra verilerle belirli uç noktaları kolayca test edebileceğim anlamına gelir:

 $args = array( 'licence_key' => 'a9e82788-5b8d-4b02-5f6a-2f6a8aa3eed3', 'product' => 'wp-migrate-db-pro', 'site_url' => 'example.com', ); $I->sendRequest( 'activate_licence', $args );

Testler aynı lisans anahtarı ve diğer veri türleri üzerinde tekrar tekrar çalıştırıldığından, her testin başında o anahtar için aboneliği temizlemenin bir yoluna ihtiyacım vardı. ApiTester.php dosyası da bu tür kodlar için iyi bir yerdir:

 public function dontSeeActivationForLicenceKey( $licence_key ) { $table = $this->grabPrefixedTableNameFor( 'woocommerce_software_licences' ); $this->dontseeInDatabase( $table, array( 'licence_key' => $licence_key ) ); }

Testlerde API isteklerini çalıştırdıktan sonra lisansın ve aboneliğin etkin olduğundan emin olmak için özel bir onay da ekledim:

 public function seeActivationForLicenceKey( $licence_key, $site_url, $check_active = false ) { $licences_table = $this->grabPrefixedTableNameFor( 'woocommerce_software_licences' ); $this->seeInDatabase( $licences_table, array( 'licence_key' => $licence_key ) ); $key_id = $this->grabFromDatabase( $licences_table, 'key_id', [ 'licence_key' => $licence_key ] ); $args = array( 'key_id' => $key_id, 'instance' => $site_url ); if ( $check_active ) { $args['activation_active'] = 1; } $activations_table = $this->grabPrefixedTableNameFor( 'woocommerce_software_activations' ); $this->seeInDatabase( $activations_table, $args ); }

Örnek Test

Burada, lisans anahtarının eksik olduğu geçersiz bir istek için testler ve başarılı bir lisans etkinleştirmesi içeren ActivateLicence uç nokta test senaryosunun bir örneği verilmiştir:

 class ActivateLicenceCest { protected $endpoint = 'activate_licence'; public function noLicenceKeyTest( ApiTester $I ) { $I->sendRequest( $this->endpoint ); $I->seeResponseIsJson(); $I->seeResponseContainsJson( array( 'errors' => array( 'no_licence_key_arg' => 'You did not provide a licence_key argument.' ) ) ); } public function validTest( ApiTester $I ) { $args = array( 'licence_key' => 'a9e82788-5b8d-4b02-5f6a-2f6a8aa3eed3', 'product' => 'wp-migrate-db-pro', 'site_url' => 'example.com', ); $I->sendRequest( $this->endpoint, $args ); $I->seeResponseIsJson(); $I->seeResponseCodeIs( 200 ); $I->seeResponseContainsJson( array( 'email' => '[email protected]' ) ); $I->seeResponseContainsJson( array( 'is_first_activation' => '0' ) ); $I->seeActivationForLicenceKey( $args['licence_key'], $args['site_url'] ); } }

Birim testinde olduğu gibi, testleri yazmanın büyük bir kısmı, koddaki tüm farklı senaryoları kapsayacak şekilde sadece geçiyor ve testler yazıyor.

Hususlar

Dosya İndirmeleri

Gelecekteki ben ve aynı şeyi yapan herkes için paylaşmaya değer tüm son noktaları kapsayan testler yazarken karşılaştığım birkaç şey vardı.

Eklentimizin güncellemeleri için zip dosyalarını müşteri web sitelerine teslim etmekten sorumlu 'indirme' uç noktasını test ederken, başarılı bir indirme isteğinin JSON'u değil, gerçek dosya verilerini döndürdüğünü fark ettim. Dosya verilerinin %100 doğru olduğunu test edecek kadar ileri gitmek istemedim ama en azından bazı verilerin döndürüldüğünden emin olmak istedim.

JSON iddialarını kullanmak yerine, kontrol etmenin en iyi yolunun, dosyanın doğru türde olduğundan ve bazı içeriklere sahip olduğundan emin olmak için yanıt için HTTP başlığını sorgulamak olduğunu buldum:

 $args = array( 'licence_key' => 'a9e82788-5b8d-4b02-5f6a-2f6a8aa3eed3', 'slug' => 'wp-migrate-db-pro', 'site_url' => 'example.com', ); $I->sendRequest( $this->endpoint, $args ); $I->seeHttpHeader( 'content-disposition', 'attachment' ); $I->seeHttpHeader( 'content-type', 'application/zip' ); $I->seeHttpHeader( 'content-length' ); $I->dontSeeHttpHeader( 'content-length', 0 );

Üçüncü kişiler

API'miz, yüklü eklentilerin içinden gönderilen müşteri destek mesajlarını e-posta destek hizmetimiz Help Scout'a göndermekten sorumludur. Bu harika bir kurulum, yani istersek eklentileri güncellemek zorunda kalmadan ve müşterilerin eklentileri sitelerinde gerçekten güncellemesine güvenmeden Help Scout'u başka bir sağlayıcıyla değiştirebiliriz.

API'nin bu bölümünü test etmek biraz zordu. Test tarafından gönderilen sahte bir destek biletinin gelip gelmediğini görmek için Yardım İzci posta kutularımızı kontrol etmenin bir yoluna ihtiyacım vardı. Help Scout için bir Codeception modülü varmış gibi görünmüyordu, ben de bir tane oluşturdum. Bu, doğru konu ve gövdeyi içerip içermediğini görmek için bir posta kutusuna gönderilen en son e-postayı kontrol etmeme izin verdi:

 $args = array( 'licence_key' => 'a9e82788-5b8d-4b02-5f6a-2f6a8aa3eed3', 'product' => 'wp-migrate-db-pro', 'site_url' => 'example.com', ); $post = array( 'email' => '[email protected]', 'subject' => 'Testing Testing', 'message' => 'This is a test message set from the API testing suite', ); // Send the API request $I->sendRequest( $this->endpoint, $args, $post ); $I->seeResponseIsJson(); $I->seeResponseContainsJson( array( 'success' => 1 ) ); $I->seeHttpHeader( 'Access-Control-Allow-Origin', '*' ); // Check Help Scout for support ticket $mailbox_id = 12345; $I->waitForEmailFromSender( $mailbox_id, $post['email'], 10 ); $I->openNextUnreadEmail(); $I->seeInOpenedEmailSubject( $post['subject'] ); $I->seeInOpenedEmailSender( $post['email'] ); $I->seeInOpenedEmailBody( $post['message'] ); $email = $I->getOpenedEmail(); $I->dontHaveEmailEmail( $email );

Bu, Codeception'ın en iyi özelliklerinden biridir – özel modüllerle çok sayıda sisteme karşı test yapabilirsiniz, çünkü tam web sitesi testi çok nadiren yalnızca tarayıcı ve veritabanına karşı doğrulama yapmakla sınırlıdır.

Testleri Çalıştırma

Ödeme işlevi için kabul testleri yazmak üzere yaptığım çalışmanın bir parçası olarak, testleri kolayca çalıştırmak için bir bash komut dosyası oluşturdum: Codeception sınıfları oluşturun, Chromedriver'ı başlatın ve kabul testlerini çalıştırın.

Ancak, şimdi üç test takımımız var – biri yönlendirmeler için site testleri ve şimdi de API olan. Bazen süitlerden birini, hatta sadece bir test senaryosunu çalıştırmak isteyebilirim, bu yüzden birkaç değişiklik yaptım:

 #!/usr/bin/env bash REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" export PATH="${REPO_DIR}/vendor/bin:${PATH}" cd "${REPO_DIR}" composer install cd "${REPO_DIR}/tests" PREFIX="tests/" SCRIPT="[email protected]" codecept build run_acceptance_tests() { kill -9 $(pgrep chromedriver) chromedriver --url-base=/wd/hub & codecept run acceptance $1 kill -9 $(pgrep chromedriver) } if [ -z "$SCRIPT" ] then # Run all test suites codecept run api codecept run redirects run_acceptance_tests else # Run specific suite test SCRIPT=${SCRIPT/#$PREFIX} SCRIPT_SUITE="${SCRIPT%%/*}" if [ $SCRIPT_SUITE = "acceptance" ]; then run_acceptance_tests $SCRIPT else codecept run $SCRIPT_SUITE $SCRIPT fi Fi

Toplama

Henüz bu testleri Travis CI ile otomatik olarak çalışacak şekilde bağlamadım, ancak geliştirme sırasında yerel olarak çalıştırılabilir olmaları iş akışım için çok yardımcı oldu. Özellikle refactor'lar gerilemelere neden olabileceğinden, değişiklik yaparken içinizin rahat etmesi çok önemlidir.

API'niz için otomatik testler kurdunuz mu? Bunu yapmak için ne kullandın? Codeception kullanan diğer WordPress şirketlerini duymakla ilgileniyorum. Aşağıdaki yorumlarda bana bildirin.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

Divi's Theme Builder ile Özel Global Başlık Nasıl Oluşturulur

Artık Tema Oluşturucu burada olduğuna göre, web sitenizi A'dan Z'ye kurmanıza yardımcı olacak yeni eğitimlere dalmak için sabırsızlanıyoruz. Buna Divi'nin yerleşik seçeneğini kullanarak özel başlıklar oluşturma da dahildir. Bu eğitimde Divi's Theme Builder'ı kullanarak global bir başlık oluşturmaya odaklanacağız. Bu sayfaya veya gönderiye farklı bir başlık atamadıysanız, web sitenizin her yerinde genel bir başlık görünecektir.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir