Site Test Sürenizi Nasıl Azaltırsınız: WooCommerce için Otomatik Kabul Testi


Manuel test süresini azaltan ve hataları yayınlanmadan önce yakalamaya yardımcı olan WordPress eklentilerimizi test etmek için otomatik kabul testini nasıl kullandığımızı daha önce yazmıştık.

Ancak yakın zamana kadar bu aynı standardı sitemizin kendisine uygulamamıştık.

Geçen yıl, eklentilerimizi sattığımız WooCommerce sitemiz lezzetlibrains.com'a bakmakla görevlendirildim (şu anda bunu okumakta olduğunuz site). Bu biraz büyük bir sorumluluk. Bir hata dağıtırsam, insanların satın almalarını engelleyebilir ve geri dönmeyebilirler! Hatalarım doğrudan ve anında kârımızı etkileyebilir. 😬

Sitede her zaman manuel testler yaptık. Aslında, daha önce 'kritik yolumuzu' kapsamlı bir şekilde test etmeyi içeren WooCommerce'i yükseltmeye yönelik kapsamlı yaklaşımımız hakkında yazmıştım:

  • PayPal ile bir eklenti satın alma
  • Stripe ile bir eklenti satın alma
  • Lisans yükseltme
  • Otomatik yenilemeyi test etme.

Ancak, her kod değişikliği yaptığımda veya bazı eklentileri güncellediğimde bu testleri manuel olarak yapmak, özellikle de otomatik testin kolaylığını bildiğim için sıkıcı olabiliyor.

Bu nedenle, bir süre önce, otomatikleştirilmiş test aracımız olan Codeception ile siteyi kurmak için biraz zaman harcadım ve tüm manuel testlerimizi yeniden oluşturdum. Aşağıda, WooCommerce çalıştıran bir WordPress sitesini test etmeye hazır hale getirmek için bazı ipuçları ve püf noktaları ile birlikte benim yaklaşımım yer alıyor.

Bu kılavuz, kritik bir yoldan endişe duyduğunuz ve test sürecinizi otomatikleştirmek istediğiniz herhangi bir WordPress sitesi (e-ticaret, üyelik veya başka bir şekilde) için de geçerli olabilir.

Başlarken

Başlamadan önce, kritik yola veya halihazırda gerçekleştirdiğiniz manuel testlere dayalı olarak yazmak istediğiniz test senaryolarını planlamak iyi bir fikirdir. Testi kimin yapacağını düşünün, örn. sitenizdeki bir müşteri veya yönetici ve sahip oldukları özellikler (oturum açma, geri dönen müşteri vb.). Bu 'aktörlerin' daha sonra ele alındığını göreceksiniz.

İlk önce Codeception'ı kurmamız ve yapılandırmamız gerekiyor:

 composer require codeception/codeception --dev vendor/bin/codecept bootstrap

WordPress sitelerini Codeception ile test ederken, kurulması gereken en önemli modül Luca Tume'un WPBrowser'ıdır:

 composer require lucatume/wp-browser --dev

WPBrowser, testlere erişmek ve bunları gerçekleştirmek için çalışan bir WordPress sitesine sahip olmanızı gerektirir. Şu anda testleri yalnızca yerel olarak yürüttüğüm için, geliştirme ve manuel test için kullandığım geliştirme sitesinin aynısını kullanıyorum.

WPBrowser, şu komutla başlatılan bazı ekstra yapılandırma gerektirir:

 vendor/bin/codecept init wpbrowser

WPBrowser, WordPress'i test etmeye yardımcı olacak bir dizi modüle sahiptir, ancak hepsinin kullanılması gerekmez. Testlerim için yalnızca WPDb ve WPWebDriver modüllerini (Chromedriver ile) kullandım.

WPDb, varsayılan Codeception Db modülünü genişletir ve WordPress veritabanı yapısı ve tabloları hakkında özel bilgiye sahiptir.

WPWebDriver, bir Selenium sunucusu, PhantomJS veya herhangi bir gerçek web tarayıcısı ile birlikte kullanılması gereken Guzzle tabanlı ve JavaScript özellikli bir web sürücüsüdür. Testlerin Javascript ile etkileşime girmesi gerekeceğinden ve testlerde hata ayıklarken neler olduğunu takip etmek çok daha kolay olduğundan, amaçlarımız için başsız bir tarayıcı yerine tarayıcı testini kullanmayı seçtim.

acceptance.suite.yml yapılandırma dosyamdaki modülleri aşağıdaki gibi yapılandırdım:

 actor: AcceptanceTester modules: enabled: - WPDb - WPWebDriver config: WPDb: dsn: 'mysql:host=%DB_HOST%;port=%DB_PORT%;dbname=%DB_NAME%' user: '%DB_USER%' password: '%DB_PASSWORD%' populate: false #import the dump before the tests cleanup: false #import the dump between tests url: '%WP_URL%' urlReplacement: true #replace the hardcoded dump URL with the one above tablePrefix: '%TABLE_PREFIX%' WPWebDriver: url: '%WP_URL%' browser: chrome window_size: false # disabled in ChromeDriver port: 9515 adminUsername: '%ADMIN_USERNAME%' adminPassword: '%ADMIN_PASSWORD%' adminUrl: /wp/wp-admin

Test Yazma

İlk testim PayPal ile bir lisans satın almak. Aşağıdakilerle hızlı bir şekilde bir test dosyası oluşturabilirsiniz:

 codecept generate:cept acceptance 00-001-PayPalOrder-Cept.php

Testimin gerçekleştirmesini istediğim ilk şey, WP Migrate DB Pro için fiyatlandırma sayfasına gitmek ve ardından 'Şimdi Satın Al'ı tıklamaktır. Eklenti lisansı sepete eklenecek ve site ödeme ekranına yönlendirilecektir.

Cept dosyama yazacağım kod bu. Codeception'ın iki test dosyası stili vardır; cept yordamsal bir stildir, oysa cest sınıf biçimindedir. Sonunda, ödeme ekranında sipariş özeti olarak doğru ürünün görüntülenip görüntülenmediğini kontrol ediyorum:

 $I = new AcceptanceTester( $scenario ); $I->wantTo('add a plugin to the cart and check it gets added'); $I->amOnPage( '/wp-migrate-db-pro/pricing' ); $I->waitForText( 'DEVELOPER' ); $I->click( '.dbi-pricing__plan--migrate-db a.dbi-btn' ); $I->waitForText( 'Order Summary', 100 ); $I->see( 'WP Migrate DB Pro' ); $I->see( 'Developer' );

Eklentiyi satın alana kadar satın alma ekranında tıklamayı ve beklemeyi simüle etmek için sadece bir kod yazma meselesi:

  • Bir test kullanıcısı ile PayPal Sandbox'a giriş yapın
  • PayPal ile ödeme
  • Görüntülenen sipariş onay ekranıyla siteye döndüğümüzden emin olun
  • Zip dosyasının indirilmesini test edin
  • Test siparişi onay e-postası alındı

Son iki adım, daha sonra değineceğim bazı özel modülleri içeriyordu.

hazırlanıyor

Bu testleri yazmanın doğası, koşacak, adımları değiştirecek ve tekrar çalıştıracak olmanızdır – çok! Bu, verilerin önceki testlerden sonra yarı pişmiş durumda değil, testler çalıştırılmadan önce doğru durumda olmasını istediğiniz anlamına gelir.

Bunu test çantamın en üstüne ekleyerek başladım, bu yüzden müşterim her zaman çıkış yaptı ve ardından kullanıcı veritabanından silindi.

 $I = new AcceptanceTester( $scenario ); $I->logOut(); $I->dontHaveUserInDatabaseWithEmail( $email );

Bunu her testin başında çağırmam gerektiğini fark ettim, bu yüzden kodu yeniden kullanılabilir hale getirmenin daha iyi bir yolunu aramaya başladım. Görünüşe göre Codeception bunu gerçekten kolaylaştırıyor.

Kod Algılamanın Genişletilmesi

Test kodumdan farkedeceğiniz gibi, ilk satır, AcceptanceTester sınıfının yeni bir örneğini oluşturur. Bu, $I değişkeni olarak saklanır, bu nedenle test kodunun doğal dilini kullanırken daha mantıklı olur. Örneğin, çıkış yapıyorum, buna tıklıyorum.

AcceptanceTester sınıfı, Codeception 'Actor' sınıfından genişler. Oyuncu, daha önce baktığım acceptance.suite.yml dosyasında tanımlanan modüllerden tüm eylemleri ve iddiaları gerçekleştirebilir.

tests/_support/Step/AcceptanceTester.php dosyasının içinde genişletilebilecek olan AcceptanceTester sınıfına yaygın olarak kullanılan kodu ekleyebilirsiniz. Örneğin, test aktörümün sitemizdeki 'Hesabım' sayfasına kolayca gitmesini istiyorsam. WPBrowser, WordPress sitesi ana url'sine göre belirli bir göreli URI için bir sayfa açmak için kullanışlı bir amOnPage yöntemi ekler. Bunu yöntemimde kullanabilirim:

 public function amOnAccount( $page = '' ) { $this->amOnPage( '/my-account/' . $page ); $this->waitForText( 'My Account' ); }

Testler çalıştırılmadan önceki temizlememin bir parçası olarak, test kullanıcısını veritabanından silmek istiyorum, ancak aynı zamanda 'wp_posts', 'wp_woocommerce_software_licences' ve ' wp_woocommerce_software_subscriptions' tabloları:

 public function dontHaveOrdersInDatabaseForEmail( $userEmail ) { $licenses = $this->grabAllFromDatabase( $this->grabPrefixedTableNameFor( 'woocommerce_software_licences' ), '*', [ 'activation_email' => $userEmail ] ); foreach ( $licenses as $license ) { $this->dontHavePostInDatabase( [ 'ID' => $license['order_id'] ] ); $this->dontHaveInDatabase( $this->grabPrefixedTableNameFor( 'woocommerce_software_licences' ), [ 'key_id' => $license['key_id'] ] ); $this->dontHaveInDatabase( $this->grabPrefixedTableNameFor( 'woocommerce_software_subscriptions' ), [ 'key_id' => $license['key_id'] ] ); } }

Özel Aktörler

Bir oyuncunun gerçekleştirebileceği tüm eylemler tarafından paylaşılmayan bazı işlevler vardır. Örneğin, bir eklenti satın alan bir müşteriyi test etmek istiyorum, ancak bir satın alma işlemini geri ödeyen bir yöneticiyi de test etmek istiyorum. Bunlar, gerçekleştirilecek farklı eylem türlerine sahip iki farklı aktör türüdür. Codeception, StepObjects biçiminde yeni aktörler oluşturmanıza olanak tanır.

Aşağıdaki komutu kullanarak hızlı bir şekilde yeni bir sınıf oluşturabilirsiniz:

 vendor/bin/codecept generate:stepobject acceptance Administrator

Bu, daha sonra özel yöntemlerimi eklediğim yeni bir tests/_support/Step/Acceptance/Administrator.php dosyası oluşturacak:

 namespace Step\Acceptance; use Codeception\Scenario; class Administrator extends \AcceptanceTester { public function __construct( Scenario $scenario ) { parent::__construct( $scenario ); $this->logOut(); $this->loginAsAdmin(); } public function refundOrder( $orderID ) { $this->amOnOrderPage( $orderID ); $this->waitForText( "Order #$orderID details" ); $this->click( 'Refund' ); $this->wait(2); $this->fillField( '.refund_order_item_qty', 1 ); $this->click( '.do-api-refund' ); $this->acceptPopup(); $this->waitForText( "Refunded" ); } }

Geri ödeme yapmak istediğim testlerimde, sipariş kimliği genellikle test veritabanımda oluşturulan son sipariş olacaktır. Bu kimliği veritabanından almak, WPDb modülünün yardımcı olacağı yöntemlere sahip olduğu bir şeydir. Aslında bir tablo ve sütun adı bağımsız değişkenlerini kabul eden grabLatestEntryByFromDatabase adlı bir yöntemi vardır. Ancak, belirli bir post_type için gönderiler tablosundan son kimliği almak istiyorum, bu durumda shop_order .

Neyse ki WPDb modülünün kendi versiyonunu yapabilir, genişletebilir ve yöntemimi ekleyebilirim. Codeception, tests/_support/Helper/ içinde yer alan 'Helper' sınıfları oluşturmanıza olanak tanır.

İşte WPDb için Yardımcım, özel grabLatestEntryByFromDatabase çalıştırmak için grabLatestEntryByFromDatabase'de bulunan benzer kodu kullandım:

 namespace Helper; class WPDb extends \Codeception\Module\WPDb { public function grabLastOrderID() { $idColumn = 'ID'; $tableName = $this->grabPostsTableName(); $postType = 'shop_order'; $dbh = $this->_getDbh(); $sth = $dbh->prepare( "SELECT {$idColumn} FROM {$tableName} WHERE post_type = '{$postType}' ORDER BY {$idColumn} DESC LIMIT 1" ); $this->debugSection( 'Query', $sth->queryString ); $sth->execute(); return $sth->fetchColumn(); } }

Codeception'ın WPDb modülümü yüklemesini sağlamak için acceptance.suite.yml dosyamı değiştirmem gerekiyor:

 actor: AcceptanceTester modules: enabled: - - WPDb + - \Helper\WPDb

Hususlar

WooCommerce Deliciousbrains.com gibi bir e-ticaret sitesini test ederken göz önünde bulundurulması gereken birkaç şey vardır. Mümkün olduğunca test etmek istiyorum, bu da üçüncü taraflarla ilgili bazı sorunları aşmak için ekstra modüller kullanmak ve kod yazmak anlamına geliyor.

Ödeme Ağ Geçitleri

Sitede iki ödeme ağ geçidi kullanıyoruz: PayPal ve Stripe. Tahmin edeceğiniz gibi, test edilmesi daha zor olan PayPal oldu 😂

Her iki ödeme ağ geçidi için de test ve korumalı alan sitelerini kullanmamızı sağlayan kodumuz zaten var, ancak PayPal için test ödemelerinde kullanmak üzere bir korumalı alan e-posta adresine ve şifreye ihtiyacınız olacak. Test paketi .env dosyası şu kimlik bilgilerini gerektirir:

 PAYPAL_SANDBOX_USERNAME=”" PAYPAL_SANDBOX_PASSWORD=""

Daha sonra test $_ENV['PAYPAL_SANDBOX_USERNAME'] gibi referans verilebilir. Stripe, kullanılabilecek test kartı detaylarına sahiptir.

Codeception'ın web tarayıcısını (Selenyum tabanlı) kullanarak PayPal oturum açma ve ödeme ekranlarında dolaşırken biraz eğlendim ve oyunlar oynadım, ancak sonunda ödeme çalışmasını sağladım, burada 'Müşteri' aktör stepObject sınıfımda bir yönteme özetlendi:

 public function checkoutPayPal() { $I = $this; $I->click( '.dbi-use-paypal a' ); // Login to PayPal Sandbox $I->waitForElementNotVisible('#preloaderSpinner', 100 ); $I->waitForText('PayPal', 100 ); $I->waitForElementVisible( '#email', 100 ); $I->fillField( 'login_email', $_ENV['PAYPAL_SANDBOX_USERNAME'] ); if ( $I->seeOnPage( 'Next' ) ) { $I->click( 'Next' ); $I->waitForElementVisible( '#password', 100 ); } $I->fillField( 'login_password', $_ENV['PAYPAL_SANDBOX_PASSWORD'] ); $I->click( 'Log In' ); $I->waitForElementNotVisible('#preloaderSpinner', 100 ); if ( $I->seeOnPage( 'Continue' ) && ! $I->seeOnPage( 'Agree and Continue' ) ) { $I->click( 'Continue' ); } $I->wait(5 ); $I->waitForText( 'Information from Delicious Brains', 100 ); // Confirm PayPal agreement $I->click( '#confirmButtonTop' ); }

Ödeme için son gönderime ulaşmadan önce PayPal'ın soru sorup sormadığını kontrol etmek için ekstra bir koşul vardır. Bu, birkaç ay önce geldi ve mevcut testleri bozdu, bu yüzden AcceptanceTester sınıfıma, eğer mevcut değilse testleri bombalamadan sayfada metin olup olmadığını test etmeme izin veren özel bir yöntem eklemek zorunda kaldım:

 /** * Check if text exists on page to be used in a conditional. * * @param string $text * * @return bool */ public function seeOnPage( $text ) { try { $this->see( $text ); } catch ( \PHPUnit\Framework\ExpectationFailedException $f ) { return false; } return true; }

e-postalar

Yeni siparişler oluşturulduğunda, site müşteriye sipariş ayrıntılarını ve yeni hesabını bildiren birkaç e-posta gönderir. Bu e-postaların gönderilip gönderilmediğini ve satın alınan şeyin eklenti adı gibi doğru bilgileri içerdiğini test etmek istiyorum.

Yerel olarak geliştirme yaparken hiçbir e-postanın gönderilmemesini sağlamak için MailTrap kullanıyoruz. WordPress'in e-posta göndermek için MailTrap'i kullanmasını sağlamak için yerel bir mu-eklenti kullanıyoruz, ancak sitenin herhangi bir geliştirici için testleri çalıştırırken bunu yapmasını sağlamak, biraz fazladan yapılandırmaya ihtiyacım olduğu anlamına geliyordu.

Testler çalışırken site için bir mu-eklenti işlevi görecek, tests/_data/mu-plugins içinde yaşayan bir PHP dosyası oluşturdum:

 if ( ! defined( 'DBRAINS_HIJACK_ALL_MAIL' ) ) { define( 'DBRAINS_HIJACK_ALL_MAIL', '[TEST_EMAIL]' ); } if ( ! defined( 'DBI_AUTO_RENEWAL_SUBSCRIPTION_LIMIT' ) ) { define( 'DBI_AUTO_RENEWAL_SUBSCRIPTION_LIMIT', 1 ); } if ( ! defined( 'DBI_AUTO_EMAIL_LIMIT' ) ) { define( 'DBI_AUTO_EMAIL_LIMIT', 1 ); } add_filter( 'option_active_plugins', function ( $plugins ) { if ( ! is_array( $plugins ) || empty( $plugins ) ) { return $plugins; } foreach ( $plugins as $key => $plugin ) { if ( 'mailgun/mailgun.php' === $plugin ) { unset( $plugins[ $key ] ); } } return $plugins; } ); add_action( 'phpmailer_init', function ( $phpmailer ) { $phpmailer->isSMTP(); $phpmailer->Host = 'smtp.mailtrap.io'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 2525; $phpmailer->Username = '[TEST_MAILTRAP_USERNAME]'; $phpmailer->Password = '[TEST_MAILTRAP_PASSWORD]'; } );

Çalışma zamanında gerçek test verileriyle değiştirilmesi gereken birkaç veri parçası vardır ve bu mu-eklentinin WordPress sitesinde yerinde olması gerekir. Bu, tests/_support/Helper içindeki Acceptance.php özel modülündeki bazı kodlarla işlenir:

 namespace Helper; // here you can define custom actions // all public methods declared in helper class will be available in $I class Acceptance extends \Codeception\Module { protected $mu_plugin = 'acceptance-testing.php'; public function _beforeSuite( $settings = [] ) { parent::_beforeSuite(); $email_plugin_contents = file_get_contents( codecept_data_dir() . 'mu-plugins/' . $this->mu_plugin ); $email_plugin_contents = str_replace( '[TEST_EMAIL]', $_ENV['ADMIN_EMAIL'], $email_plugin_contents ); $email_plugin_contents = str_replace( '[TEST_MAILTRAP_USERNAME]', $_ENV['MAILTRAP_USERNAME'], $email_plugin_contents ); $email_plugin_contents = str_replace( '[TEST_MAILTRAP_PASSWORD]', $_ENV['MAILTRAP_PASSWORD'], $email_plugin_contents ); $this->deleteEmailPlugin(); file_put_contents( dirname( codecept_root_dir() ) . '/public_html/content/mu-plugins/' . $this->mu_plugin, $email_plugin_contents ); } public function _afterSuite() { parent::_afterSuite(); $this->deleteEmailPlugin(); } protected function deleteEmailPlugin() { $email_plugin = dirname( codecept_root_dir() ) . '/public_html/content/mu-plugins/' . $this->mu_plugin; if ( file_exists( $email_plugin ) ) { unlink( $email_plugin ); } } }

E-postaları gerçekten test etmeye gelince, MailTrap için MailTrap gelen kutunuza bakmanıza ve e-postalar hakkında iddialarda bulunmanıza izin veren bir üçüncü taraf Codeception modülü vardır. Örneğin, bu satırlar, gövdesinde belirtilen metni içeren bir e-postanın gelmesini bekler, ardından konu ve gövdedeki metni kontrol eder:

 $I->waitForEmailWithTextInHTMLBody( 'Order Complete', 100 ); $I->seeInEmailSubject( 'Order Complete' ); $I->seeInEmailHtmlBody( 'WP Migrate DB Pro - Developer' );

Gelecekte bu modülü genişletmeyi planlıyorum, böylece tüm stil ve biçimlendirmenin doğru olduğundan emin olmak ve tüm bağlantıların doğru çalıştığını test etmek için kaydedilmiş bir kopyaya karşı gönderilen e-postaları test edebilirim.

Testleri Çalıştırma

Bu testlerin hızlı ve kolay bir şekilde çalışması için, Codeception build komutunu çalıştıran, mevcut Chromedriver işlemlerini öldüren, Chromedriver'ı başlatan ve sonunda testlerin kabul paketini çalıştıran bir bash dosyası tests/bin/run-acceptancetests.sh kullanıyorum.

 #!/usr/bin/env bash REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" export PATH="${REPO_DIR}/vendor/bin:${PATH}" cd "${REPO_DIR}/tests" codecept build kill -9 $(pgrep chromedriver) chromedriver --url-base=/wd/hub & codecept run acceptance "[email protected]" kill -9 $(pgrep chromedriver)

Sonunda bu testleri çekme isteklerinin yaşam döngüsünün bir parçası olarak Travis tarafından çalıştırılmasını istiyorum, ancak büyük olasılıkla başka bir gönderi için yapılabilecek bazı yapılandırma zorlukları olacaktır.

Sıradaki ne

Bu test setine sahip olmak siteyi geliştirirken bana huzur verdi ve daha da önemlisi hayatımı kolaylaştırdı! Her zaman manuel, sıkıcı, test yapmak zorunda değilim.

Ayrıca, lisanslama API'miz ve e-posta pazarlama hizmetimizle etkileşimler gibi sitenin birçok önemli özelliğini tamamen denemek ve tamamen kapsamak için daha sonra daha fazla test ekleyebilirim.

Sitenizde otomatik test yapıyor musunuz? Hangi araçları kullanıyorsun? Yorumlarda bize 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