Rumah >pembangunan bahagian belakang >tutorial php >Uji Semua Logik Perniagaan anda dalam masa kurang dari econd
Artikel ini bukan tentang ujian. Ini mengenai penggunaan aliran kerja yang memastikan anda mengawal semasa membangunkan ciri anda. Ujian hanyalah enjin dan akibat gembira dari proses ini.
Aliran kerja ini telah mengubah sepenuhnya cara saya mengekod, dan ia tidak pernah gagal untuk memberikan senyuman di wajah saya. Harapan saya ialah ia melakukan perkara yang sama untuk anda. Pada akhirnya, anda akan mempunyai ciri yang dibangunkan sepenuhnya yang memenuhi semua peraturan perniagaan dan set ujian yang mengesahkannya dalam masa kurang dari satu saat.
Saya menggunakan PHP untuk demonstrasi, tetapi aliran kerja ini boleh disesuaikan sepenuhnya kepada mana-mana bahasa.
Apabila tiba masanya untuk membangunkan ciri baharu, selalunya sukar untuk mengetahui di mana hendak bermula. Sekiranya anda bermula dengan logik perniagaan, pengawal atau bahagian hadapan ?
Sama-sama sukar untuk mengetahui masa untuk berhenti. Tanpa proses yang jelas, satu-satunya cara untuk mengukur kemajuan anda ialah melalui ujian manual. Pendekatan yang membosankan dan terdedah kepada kesilapan.
Anda tahu yang satu. Fail itu di mana perkara yang tidak dapat dijelaskan berlaku. Anda perlu menukar satu baris, tetapi setiap percubaan seolah-olah memecahkan keseluruhan projek. Tanpa jaring keselamatan ujian, pemfaktoran semula terasa seperti berjalan di atas tali yang ketat di atas ngarai.
Untuk mengelakkan kekecohan ini, anda memutuskan untuk menguji setiap ciri dengan ujian hujung ke hujung. Idea yang bagus! Sehingga anda sedar anda mempunyai masa yang cukup untuk minum lima cawan kopi sementara menunggu suite ujian selesai. Produktiviti ? Di luar tingkap.
Dalam usaha untuk mencipta maklum balas segera, anda memutuskan untuk menulis ujian terperinci untuk semua kelas anda. Walau bagaimanapun, kini setiap perubahan yang anda lakukan membawa kepada rangkaian ujian yang rosak, dan anda akhirnya menghabiskan lebih banyak masa untuk membetulkannya daripada mengerjakan perubahan sebenar. Ia mengecewakan, tidak cekap dan membuatkan anda takut setiap faktor semula.
Maklum balas adalah penting pada setiap peringkat pembangunan perisian. Semasa membangunkan teras projek, saya memerlukan maklum balas segera untuk mengetahui dengan segera jika mana-mana peraturan perniagaan saya dilanggar. Semasa pemfaktoran semula, mempunyai pembantu yang memberitahu saya sama ada kod itu rosak atau jika saya boleh meneruskan dengan selamat merupakan kelebihan yang tidak ternilai.
Apa yang projek mampu lakukan, tingkah laku projek, adalah aspek yang paling penting. Tingkah laku ini harus berpusatkan pengguna. Walaupun pelaksanaan (kod yang dibuat untuk membuat ciri berfungsi) berubah, niat pengguna akan tetap sama.
Sebagai contoh, apabila pengguna membuat pesanan produk, mereka ingin dimaklumkan. Terdapat banyak cara untuk memberitahu pengguna: e-mel, SMS, mel, dll. Walaupun niat pengguna tidak berubah, pelaksanaan selalunya akan berubah.
Jika ujian mewakili niat pengguna dan kod tidak lagi memenuhi hasrat itu, ujian itu sepatutnya gagal. Walau bagaimanapun, semasa pemfaktoran semula, jika kod masih memenuhi hasrat pengguna, ujian itu tidak sepatutnya pecah.
Bayangkan dibimbing langkah demi langkah melalui penciptaan ciri baharu. Dengan menulis ujian terlebih dahulu, ia menjadi panduan anda untuk mengekodkan ciri yang betul. Ia mungkin belum jelas sepenuhnya, tetapi saya mahu ujian saya berfungsi sebagai GPS saya semasa saya mengekod. Dengan pendekatan ini, saya tidak perlu memikirkan langkah seterusnya, saya hanya mengikut arahan GPS. Jika konsep ini masih belum jelas, jangan risau! Saya akan menerangkannya secara terperinci dalam bahagian aliran kerja. ?
Seperti yang saya nyatakan dalam pengenalan, artikel ini bukan tentang ujian—ia tentang mencipta ciri. Dan untuk melakukan itu, saya memerlukan ciri. Lebih khusus lagi, saya memerlukan ciri yang disertakan dengan ujian penerimaan yang ditakrifkan dengan contoh. Untuk setiap ciri, pasukan harus menetapkan kriteria atau peraturan penerimaan dan bagi setiap peraturan, cipta satu atau lebih contoh.
⚠️ Contoh ini mestilah berasaskan pengguna/domain, tanpa aspek teknikal yang diterangkan. Cara mudah untuk menyemak sama ada contoh anda ditakrifkan dengan baik adalah dengan bertanya kepada diri sendiri: "Adakah contoh saya akan berfungsi dengan mana-mana pelaksanaan (bahagian hadapan Web, API HTTP, Terminal CLI, Kehidupan sebenar, dll.)?"
Sebagai contoh, jika saya ingin membangunkan ciri "Tambah produk ke bakul", contoh saya mungkin kelihatan seperti ini:
Contoh ini akan berfungsi sebagai asas untuk ujian. Untuk senario yang lebih kompleks, saya menggunakan corak Given/When/Then untuk perincian tambahan, tetapi ia tidak perlu untuk yang lebih mudah.
Maklum balas segera dan tumpuan pada tingkah laku, bukankah itu agak mencabar? Dengan seni bina Symfony MVC Services, mencapai ini boleh menjadi sukar. Itulah sebabnya saya akan menggunakan seni bina tertumpu domain, yang telah saya perincikan dalam artikel ini: Satu Lagi Cara untuk Menstruktur Projek Symfony Anda.
Untuk memfokuskan pada tingkah laku, saya perlu menstruktur ujian dengan cara yang betul. Pertama, saya menerangkan keadaan sistem sebelum tindakan pengguna. Seterusnya, saya melaksanakan tindakan pengguna, yang mengubah keadaan sistem. Akhir sekali, saya menegaskan bahawa keadaan sistem sepadan dengan jangkaan saya.
Dengan menguji cara ini, ujian tidak peduli bagaimana tindakan pengguna dikendalikan oleh sistem; ia hanya menyemak sama ada tindakan itu berjaya atau tidak. Ini bermakna jika kami menukar pelaksanaan tindakan pengguna, ujian tidak akan putus. Walau bagaimanapun, jika pelaksanaan gagal mengemas kini keadaan sistem seperti yang dijangkakan, ujian akan rosak—dan itulah yang kami mahukan!
Untuk mencapai maklum balas segera, mengejek bahagian tertentu sistem diperlukan. Seni bina berpusatkan domain menjadikan ini mungkin kerana domain bergantung semata-mata pada antara muka untuk berinteraksi dengan perpustakaan luaran. Ini menjadikannya sangat mudah untuk memalsukan kebergantungan tersebut, membolehkan ujian berfungsi berjalan dengan sangat pantas. Sudah tentu, pelaksanaan sebenar juga akan diuji (walaupun bukan dalam artikel ini) menggunakan ujian integrasi.
Dalam aliran kerja ini, ujian ialah GPS saya! Saya menetapkan destinasi, biarkan ia membimbing saya dan memberitahu saya apabila saya tiba. Ujian akan terbentuk berdasarkan contoh yang diberikan oleh pasukan.
Untuk menguji logik perniagaan dan niat pengguna, saya menggunakan ujian berfungsi :
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket() { } }
Fail ini akan mengandungi semua ujian untuk ciri ini, tetapi mari kita mulakan dengan yang pertama.
Dalam bahagian pertama, saya menerangkan keadaan aplikasi. Di sini, terdapat bakul kosong untuk pelanggan dengan id "1".
$customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]);
Pengendali dan arahan mewakili niat pengguna, seperti ini jelas dan semua orang faham.
$commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId));
? : Saya memutuskan untuk memisahkan arahan dan pertanyaan dalam projek ini, tetapi kita boleh mempunyai AddProductToBasketUseCase.
Akhir sekali, tiba masanya untuk menerangkan bagaimana keputusan akhir sepatutnya kelihatan. Saya menjangkakan untuk mempunyai produk yang betul dalam bakul saya.
$expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]);
Berikut ialah ujian yang menterjemahkan contoh pertama kepada kod.
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket(): void { // Arrange $customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]); // Act $commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId)); // Assert $expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]); } }
Pada ketika ini, IDE saya menunjukkan ralat di mana-mana kerana tiada apa yang saya gunakan dalam ujian ini wujud lagi. Tetapi adakah ini benar-benar kesilapan, atau adakah ia hanyalah langkah seterusnya ke arah destinasi kita? Saya menganggap ralat ini sebagai arahan, setiap kali saya menjalankan ujian, ia akan memberitahu kami apa yang perlu dilakukan seterusnya. Dengan cara ini, saya tidak perlu terlalu berfikir; Saya hanya mengikut GPS.
? Petua: Untuk meningkatkan pengalaman pembangun, anda boleh mendayakan pemerhati fail yang menjalankan suite ujian secara automatik apabila anda membuat perubahan. Memandangkan suite ujian adalah sangat pantas, anda akan mendapat maklum balas segera pada setiap kemas kini.
Dalam contoh ini, saya akan menangani setiap ralat satu demi satu. Sudah tentu, jika anda berasa yakin, anda boleh mengambil jalan pintas di sepanjang jalan. ?
Jadi, mari jalankan ujian! Untuk setiap ralat, saya akan melakukan minimum yang diperlukan untuk meneruskan ke langkah seterusnya.
❌ ? : "Ralat : Kelas "AppTestsFunctionalBasket" tidak ditemui"
Memandangkan ia adalah ujian pertama untuk ciri ini, kebanyakan kelas belum wujud lagi. Jadi langkah pertama, saya mencipta objek Bakul :
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket() { } }
❌ ? : "Ralat : Kelas "AppTestsFunctionalInMemoryBasketRepository" tidak ditemui"
Saya mencipta InMemoryBasketRepository :
$customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]);
❌ ? : "Ralat : Kelas "AppTestsFunctionalAddProductToBasketCommandHandler" tidak ditemui"
Saya mencipta AddProductToBasketCommandHandler dalam folder Catalog/Application, pengendali ini akan menjadi titik masuk untuk ciri "Tambah produk ke bakul".
$commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId));
Untuk menghormati seni bina tertumpu domain, saya mencipta antara muka untuk repositori, seperti ini kita terbalikkan kebergantungan.
$expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]);
❌ ? : "TypeError : AppCatalogApplicationCommandAddProductToBasketAddProductToBasketCommandHandler::__construct(): Argument #1 ($basketRepository) mestilah dari jenis AppCatalogDomainBasketRepository, AppCatalogInfrastructureRepositoryPersistenceIn diberikan"
Kini, pelaksanaan InMemory mesti melaksanakan antara muka untuk dapat disuntik dalam pengendali arahan.
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket(): void { // Arrange $customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]); // Act $commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId)); // Assert $expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]); } }
❌ ? : _"Ralat : Kelas "AppTestsFunctionalAddProductToBasketCommand" tidak ditemui"
_
Saya mencipta perintah, memandangkan perintah a sentiasa DTO, saya menandainya sebagai baca sahaja dan meletakkan semua sifat awam.
// src/Catalog/Domain/Basket.php namespace App\Catalog\Domain; class Basket { public function __construct( public readonly string $id, public readonly string $customerId, public array $products = [], ) { } }
❌ ? : "Gagal menegaskan bahawa dua objek adalah sama."
Ujian sedang menyusun! Ia masih merah, jadi kita belum selesai, mari teruskan! ?
Sudah tiba masanya untuk mengekodkan logik perniagaan. Sama seperti semasa saya menulis ujian, walaupun tiada apa-apa lagi, saya menulis bagaimana saya mengharapkan pengendali saya memproses arahan. Ia tidak akan menyusun, tetapi sekali lagi, ujian akan membimbing saya ke langkah seterusnya.
// src/Catalog/Infrastructure/Persistence/InMemory/InMemoryBasketRepository.php namespace App\Catalog\Infrastructure\Persistence\InMemory; class InMemoryBasketRepository { public function __construct( public array $baskets ) { } }
❌ ? : "Ralat : Panggilan ke kaedah yang tidak ditentukan AppCatalogInfrastructurePersistenceInMemoryInMemoryBasketRepository::get()"
Saya mencipta kaedah get dalam antara muka repositori :
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket() { } }
❌ ? : "PHP Fatal error: Class AppCatalogInfrastructurePersistenceInMemoryInMemoryBasketRepository mengandungi 1 kaedah abstrak dan oleh itu mesti diisytiharkan sebagai abstrak atau melaksanakan kaedah yang selebihnya (AppCatalogDomainBasketRepository::get)"
Dan kini saya melaksanakannya dalam repositori InMemory. Memandangkan ia hanya untuk menguji, saya mencipta pelaksanaan yang sangat mudah :
$customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]);
❌ ? : "Ralat : Panggilan ke kaedah yang tidak ditentukan AppCatalogDomainBasket::add()"
Saya mencipta kaedah tambah dan melaksanakannya pada objek bakul
$commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId));
❌ ? : Ralat : Panggilan ke kaedah yang tidak ditentukan AppCatalogInfrastructurePersistenceInMemoryInMemoryBasketRepository::save()
Sama di sini, saya mencipta kaedah dalam antara muka dan saya melaksanakannya dalam repositori dalam memori :
$expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]);
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket(): void { // Arrange $customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]); // Act $commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId)); // Assert $expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]); } }
✅ ? :
Destinasi telah sampai! ? ? ?
Dengan aliran kerja ini, saya telah menggabungkan pengalaman pembangun. Selepas cabaran untuk menangani ujian merah, melihatnya bertukar hijau memberi anda suntikan dopamin ??
Untuk membuat ujian lulus, saya sengaja pergi agak cepat. Kini, saya boleh meluangkan masa untuk memperhalusi ujian dan melaksanakan kod dengan cara yang lebih baik.
Ujian menterjemah contoh tetapi kehilangan niat pengguna semasa terjemahan. Dengan beberapa fungsi, saya boleh menjadikannya lebih dekat dengan contoh asal.
Contoh :
Ujian :
// src/Catalog/Domain/Basket.php namespace App\Catalog\Domain; class Basket { public function __construct( public readonly string $id, public readonly string $customerId, public array $products = [], ) { } }
Ini bukan fokus artikel ini, jadi saya tidak akan menerangkan secara terperinci, tetapi saya boleh menyatakan model domain dengan lebih tepat menggunakan model domain kaya.
Memandangkan ujian berwarna hijau, kini saya boleh refactor seberapa banyak yang saya mahu, ujian itu ada di belakang saya. ?
Seperti yang anda lihat pada permulaan artikel, satu ciri mempunyai banyak contoh untuk menerangkannya. Jadi sudah tiba masanya untuk melaksanakan kesemuanya :
// src/Catalog/Infrastructure/Persistence/InMemory/InMemoryBasketRepository.php namespace App\Catalog\Infrastructure\Persistence\InMemory; class InMemoryBasketRepository { public function __construct( public array $baskets ) { } }
Saya telah mengikuti aliran kerja ini beberapa kali dengan ujian yang berbeza dan pelbagai bahagian kod saya telah berkembang untuk diselaraskan dengan peraturan perniagaan. Seperti yang anda lihat dengan ujian pertama, objek saya sangat mudah dan kadangkala asas. Walau bagaimanapun, apabila peraturan perniagaan baharu diperkenalkan, mereka mendorong saya untuk membangunkan model domain yang lebih bijak. Inilah struktur folder saya :
Untuk memudahkan ujian sambil mengekalkan enkapsulasi model domain, saya memperkenalkan pembina dan corak syot kilat.
// tests/Functional/AddProductToBasketTest.php namespace App\Tests\Functional; use PHPUnit\Framework\TestCase; class AddProductToBasketTest extends TestCase { public function testAddProductToBasket() { } }
$customerId = 1; $productId = 1; $basketId = 1; $basket = new Basket($basketId, customerId: $customerId); $inMemoryBasketRepository = new InMemoryBasketRepository(baskets: [$basket]);
$commandHandler = new AddProductToBasketCommandHandler( $inMemoryBasketRepository, ); $commandHandler(new AddProductToBasketCommand(customerId: $customerId, basketId: $basketId, productId: $productId));
Cara saya menggunakannya :
$expectedBasket = new Basket($basketId, $customerId, array($productId)); $this->assertEquals($expectedBasket, $inMemoryBasketRepository->baskets[0]);
Memandangkan saya tertumpu sepenuhnya pada logik perniagaan, ujian saya membimbing saya pada setiap langkah, memberitahu saya perkara yang perlu dilakukan setiap kali saya menambah kod baharu. Selain itu, saya tidak lagi perlu melakukan ujian manual untuk memastikan semuanya berfungsi, yang meningkatkan kecekapan saya dengan ketara.
Dalam artikel ini, saya menunjukkan contoh yang sangat mudah di mana saya kebanyakannya mencipta kelas. Walau bagaimanapun, dengan logik perniagaan yang lebih kompleks, setiap peraturan baharu akan menambah kerumitan pada model domain. Semasa pemfaktoran semula, matlamat saya adalah untuk memudahkan model domain sambil mengekalkan ujian hijau. Ia adalah satu cabaran yang sebenar—tetapi satu cabaran yang sangat memuaskan apabila akhirnya berjaya.
Apa yang saya tunjukkan di sini hanyalah bahagian pertama aliran kerja yang lengkap. Seperti yang saya nyatakan, untuk mempunyai ciri berfungsi sepenuhnya, saya masih perlu melaksanakan penyesuai sebenar. Dalam kes ini, ini termasuk mencipta repositori (Bakul, Pelanggan dan Produk) menggunakan pendekatan ujian pertama dengan pangkalan data sebenar. Setelah itu selesai, saya hanya akan mengkonfigurasi pelaksanaan sebenar dalam konfigurasi suntikan pergantungan.
Saya menggunakan PHP tulen tanpa bergantung pada sebarang rangka kerja, memfokuskan semata-mata pada merangkum semua logik perniagaan. Dengan strategi ini, saya tidak perlu risau lagi tentang prestasi ujian. Sama ada terdapat beratus-ratus atau bahkan beribu-ribu ujian, mereka akan tetap berjalan dalam beberapa saat sahaja, memberikan maklum balas segera semasa pengekodan.
Untuk memberi anda petunjuk prestasi, berikut ialah set ujian diulang 10,000 kali:
Aliran kerja ini terletak di persimpangan beberapa konsep. Izinkan saya memperkenalkan beberapa daripadanya supaya anda boleh menerokanya dengan lebih lanjut jika perlu.
Untuk menerangkan ciri, pendekatan terbaik ialah memberikan seberapa banyak contoh yang perlu. Mesyuarat pasukan boleh membantu anda memperoleh pemahaman yang mendalam tentang ciri tersebut dengan mengenal pasti contoh konkrit tentang cara ciri tersebut berfungsi.
Rangka kerja Given-When-Then ialah alat yang hebat untuk memformalkan contoh ini.
Untuk menterjemah contoh ini kepada kod, bahasa Gherkin (dengan Behat dalam PHP) boleh membantu. Walau bagaimanapun, saya secara peribadi lebih suka bekerja secara langsung dalam ujian PHPUnit dan menamakan fungsi saya menggunakan kata kunci ini.
"apa yang kita mahu?" sebahagian boleh diringkaskan dengan akronim F.I.R.S.T :
Kini anda mempunyai senarai semak untuk mengetahui sama ada ujian anda dibuat dengan baik.
Semua seni bina ini bertujuan untuk mengasingkan logik perniagaan daripada butiran pelaksanaan. Sama ada anda menggunakan Pelabuhan dan Penyesuai, Heksagon atau Seni Bina Bersih, idea terasnya ialah menjadikan rangka kerja logik perniagaan-agnostik dan mudah untuk diuji.
Sebaik sahaja anda memikirkan perkara ini, terdapat spektrum penuh pelaksanaan dan yang terbaik bergantung pada konteks dan pilihan anda. Kelebihan utama seni bina ini ialah, dengan mengasingkan logik perniagaan, ia membolehkan ujian yang lebih cekap.
Saya rasa anda sudah biasa dengan piramid ujian, sebaliknya saya lebih suka menggunakan perwakilan berlian. Strategi ini, yang diterangkan oleh Thomas Pierrain, adalah didorong kes penggunaan dan memfokuskan pada gelagat aplikasi kami.
Strategi ini juga menggalakkan ujian kotak hitam aplikasi, memfokuskan pada hasil yang dihasilkan dan bukannya cara ia menghasilkannya. Pendekatan ini menjadikan pemfaktoran semula lebih mudah.
Seperti yang anda lihat sepanjang aliran kerja, dalam ujian dan dalam pengendali arahan, saya sentiasa menulis apa yang saya mahu sebelum ia wujud. Saya membuat beberapa "keinginan". Pendekatan ini dikenali sebagai pengaturcaraan angan-angan. Ia membolehkan anda membayangkan struktur sistem anda dan cara yang ideal untuk berinteraksi dengannya sebelum memutuskan cara untuk melaksanakannya. Apabila digabungkan dengan ujian, ia menjadi kaedah yang berkuasa untuk membimbing pengaturcaraan anda.
Corak ini membantu ujian struktur dengan berkesan. Pertama, sistem ditetapkan kepada keadaan awal yang betul. Seterusnya, pengubah keadaan, seperti arahan atau tindakan pengguna, dilaksanakan. Akhir sekali, penegasan dibuat untuk memastikan sistem berada dalam keadaan yang dijangkakan selepas tindakan.
Kami telah meneliti cara seni bina tertumpu domain digabungkan dengan pembangunan didorong ujian penerimaan boleh mengubah pengalaman pembangunan anda. Maklum balas segera, ujian mantap dan tumpuan pada niat pengguna menjadikan pengekodan bukan sahaja lebih cekap tetapi lebih menyeronokkan.
Cuba aliran kerja ini, dan anda mungkin mendapati diri anda tersenyum setiap kali ujian bertukar menjadi hijau ✅ ➡️ ?
Beri tahu saya dalam ulasan apakah aliran kerja anda yang sempurna atau apakah yang akan anda perbaiki dalam yang ini!
Atas ialah kandungan terperinci Uji Semua Logik Perniagaan anda dalam masa kurang dari econd. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!