Dalam siaran ini, kami akan meneroka cara membawa minda ujian unit PHP, terutamanya pendekatan penyedia data rangka kerja PHPUnit, ke dalam Go. Jika anda seorang pembangun PHP yang berpengalaman, anda mungkin biasa dengan model pembekal data: mengumpulkan data ujian secara berasingan dalam tatasusunan mentah dan memasukkan data ini ke dalam fungsi ujian. Pendekatan ini menjadikan ujian unit lebih bersih, lebih boleh diselenggara dan mematuhi prinsip seperti Terbuka/Tertutup.
Menggunakan pendekatan penyedia data untuk menstruktur ujian unit dalam Go memberikan beberapa kelebihan, termasuk:
Kebolehbacaan dan Kebolehlanjutan Dipertingkat: Ujian menjadi teratur secara visual, dengan tatasusunan yang dipisahkan dengan jelas di bahagian atas mewakili setiap senario ujian. Setiap kunci tatasusunan menerangkan senario, manakala kandungannya memegang data untuk menguji senario tersebut. Struktur ini menjadikan fail senang dikerjakan dan mudah dipanjangkan.
Pengasingan Kebimbangan: Model pembekal data menyimpan data dan logik ujian, menghasilkan fungsi yang ringan dan dipisahkan yang sebahagian besarnya boleh kekal tidak berubah dari semasa ke semasa. Menambah senario baharu hanya memerlukan penambahan lebih banyak data kepada pembekal, memastikan fungsi ujian terbuka untuk sambungan tetapi ditutup untuk pengubahsuaian—aplikasi praktikal Prinsip Terbuka/Tertutup dalam ujian.
Dalam sesetengah projek, saya juga pernah melihat senario yang cukup padat untuk menjamin penggunaan fail JSON yang berasingan sebagai sumber data, dibina secara manual dan disalurkan kepada pembekal, yang seterusnya membekalkan data kepada fungsi ujian.
Penggunaan penyedia data amat digalakkan apabila anda mempunyai sejumlah besar kes ujian dengan data yang berbeza-beza: setiap kes ujian adalah sama secara konsep tetapi berbeza hanya dalam input dan output yang dijangkakan.
Menggabungkan data dan logik dalam satu fungsi ujian boleh mengurangkan Pengalaman Pembangun (DX). Ia selalunya membawa kepada:
Verbosity Overload: Kod berlebihan yang mengulangi pernyataan dengan sedikit variasi data, yang membawa kepada pangkalan kod yang bertele-tele tanpa faedah tambahan.
Kejelasan yang Dikurangkan: Mengimbas melalui fungsi ujian menjadi tugasan apabila cuba mengasingkan data ujian sebenar daripada kod sekeliling, yang mana pendekatan pembekal data secara semulajadi mengurangkannya.
Corak DataProvider dalam PHPUnit di mana pada asasnya fungsi pembekal membekalkan fungsi ujian dengan set data berbeza yang digunakan dalam gelung tersirat. Ia memastikan prinsip DRY (Don't Repeat Yourself) dan sejajar dengan Prinsip Terbuka/Tertutup juga, dengan memudahkan untuk menambah atau mengubah suai senario ujian tanpa mengubah logik fungsi ujian teras.
Untuk menggambarkan kelemahan verbositi, pertindihan kod dan cabaran penyelenggaraan, berikut ialah coretan contoh ujian unit untuk fungsi isihan gelembung tanpa bantuan penyedia data:
<?php declare(strict_types=1); use PHPUnit\Framework\TestCase; final class BubbleSortTest extends TestCase { public function testBubbleSortEmptyArray() { $this->assertSame([], BubbleSort([])); } public function testBubbleSortOneElement() { $this->assertSame([0], BubbleSort([0])); } public function testBubbleSortTwoElementsSorted() { $this->assertSame([5, 144], BubbleSort([5, 144])); } public function testBubbleSortTwoElementsUnsorted() { $this->assertSame([-7, 10], BubbleSort([10, -7])); } public function testBubbleSortMultipleElements() { $this->assertSame([1, 2, 3, 4], BubbleSort([1, 3, 4, 2])); } // And so on for each test case, could be 30 cases for example. public function testBubbleSortDescendingOrder() { $this->assertSame([1, 2, 3, 4, 5], BubbleSort([5, 4, 3, 2, 1])); } public function testBubbleSortBoundaryValues() { $this->assertSame([-2147483647, 2147483648], BubbleSort([2147483648, -2147483647])); } }
Adakah terdapat masalah dengan kod di atas? pasti:
Verbosity: Setiap kes ujian memerlukan kaedah yang berasingan, menghasilkan asas kod berulang yang besar.
Penduaan: Logik ujian diulang dalam setiap kaedah, hanya berbeza mengikut input dan output yang dijangkakan.
Pelanggaran Terbuka/Tertutup: Menambah kes ujian baharu memerlukan mengubah struktur kelas ujian dengan mencipta lebih banyak kaedah.
Berikut ialah suite ujian yang sama yang difaktorkan semula untuk menggunakan pembekal data
<?php declare(strict_types=1); use PHPUnit\Framework\TestCase; final class BubbleSortTest extends TestCase { /** * Provides test data for bubble sort algorithm. * * @return array<string, array> */ public function bubbleSortDataProvider(): array { return [ 'empty' => [[], []], 'oneElement' => [[0], [0]], 'twoElementsSorted' => [[5, 144], [5, 144]], 'twoElementsUnsorted' => [[10, -7], [-7, 10]], 'moreThanOneElement' => [[1, 3, 4, 2], [1, 2, 3, 4]], 'moreThanOneElementWithRepetition' => [[1, 4, 4, 2], [1, 2, 4, 4]], 'moreThanOneElement2' => [[7, 7, 1, 0, 99, -5, 10], [-5, 0, 1, 7, 7, 10, 99]], 'sameElement' => [[1, 1, 1, 1], [1, 1, 1, 1]], 'negativeNumbers' => [[-5, -2, -10, -1, -3], [-10, -5, -3, -2, -1]], 'descendingOrder' => [[5, 4, 3, 2, 1], [1, 2, 3, 4, 5]], 'randomOrder' => [[9, 2, 7, 4, 1, 6, 3, 8, 5], [1, 2, 3, 4, 5, 6, 7, 8, 9]], 'duplicateElements' => [[2, 2, 1, 1, 3, 3, 4, 4], [1, 1, 2, 2, 3, 3, 4, 4]], 'largeArray' => [[-1, -10000, -12345, -2032, -23, 0, 0, 0, 0, 10, 10000, 1024, 1024354, 155, 174, 1955, 2, 255, 3, 322, 4741, 96524], [-1, -10000, -12345, -2032, -23, 0, 0, 0, 0, 10, 10000, 1024, 1024354, 155, 174, 1955, 2, 255, 3, 322, 4741, 96524]], 'singleNegativeElement' => [[-7], [-7]], 'arrayWithZeroes' => [[0, -2, 0, 3, 0], [-2, 0, 0, 0, 3]], 'ascendingOrder' => [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]], 'descendingOrderWithDuplicates' => [[5, 5, 4, 3, 3, 2, 1], [1, 2, 3, 3, 4, 5, 5]], 'boundaryValues' => [[2147483648, -2147483647], [-2147483647, 2147483648]], 'mixedSignNumbers' => [[-1, 0, 1, -2, 2], [-2, -1, 0, 1, 2]], ]; } /** * @dataProvider bubbleSortDataProvider * * @param array<int> $input * @param array<int> $expected */ public function testBubbleSort(array $input, array $expected) { $this->assertSame($expected, BubbleSort($input)); } }
Adakah terdapat sebarang kelebihan menggunakan pembekal data? oh ya:
Keringkas: Semua data ujian dipusatkan dalam satu kaedah, menghilangkan keperluan untuk berbilang fungsi untuk setiap senario.
Kebolehbacaan Dipertingkat: Setiap kes ujian disusun dengan baik, dengan kunci deskriptif untuk setiap senario.
Prinsip Terbuka/Tertutup: Kes baharu boleh ditambahkan pada pembekal data tanpa mengubah logik ujian teras.
DX (Pengalaman Pembangun) yang Dipertingkatkan: Struktur ujian bersih, menarik perhatian, menjadikan pembangun yang malas itu terdorong untuk melanjutkan, nyahpepijat atau mengemas kininya.
package sort import ( "testing" "github.com/stretchr/testify/assert" ) type TestData struct { ArrayList map[string][]int ExpectedList map[string][]int } const ( maxInt32 = int32(^uint32(0) >> 1) minInt32 = -maxInt32 - 1 ) var testData = &TestData{ ArrayList: map[string][]int{ "empty": {}, "oneElement": {0}, "twoElementsSorted": {5, 144}, "twoElementsUnsorted": {10, -7}, "moreThanOneElement": {1, 3, 4, 2}, "moreThanOneElementWithRepetition": {1, 4, 4, 2}, "moreThanOneElement2": {7, 7, 1, 0, 99, -5, 10}, "sameElement": {1, 1, 1, 1}, "negativeNumbers": {-5, -2, -10, -1, -3}, "descendingOrder": {5, 4, 3, 2, 1}, "randomOrder": {9, 2, 7, 4, 1, 6, 3, 8, 5}, "duplicateElements": {2, 2, 1, 1, 3, 3, 4, 4}, "largeArray": {-1, -10000, -12345, -2032, -23, 0, 0, 0, 0, 10, 10000, 1024, 1024354, 155, 174, 1955, 2, 255, 3, 322, 4741, 96524}, "singleNegativeElement": {-7}, "arrayWithZeroes": {0, -2, 0, 3, 0}, "ascendingOrder": {1, 2, 3, 4, 5}, "descendingOrderWithDuplicates": {5, 5, 4, 3, 3, 2, 1}, "boundaryValues": {2147483648, -2147483647}, "mixedSignNumbers": {-1, 0, 1, -2, 2}, }, ExpectedList: map[string][]int{ "empty": {}, "oneElement": {0}, "twoElementsSorted": {5, 144}, "twoElementsUnsorted": {-7, 10}, "moreThanOneElement": {1, 2, 3, 4}, "moreThanOneElementWithRepetition": {1, 2, 4, 4}, "moreThanOneElement2": {-5, 0, 1, 7, 7, 10, 99}, "sameElement": {1, 1, 1, 1}, "negativeNumbers": {-10, -5, -3, -2, -1}, "descendingOrder": {1, 2, 3, 4, 5}, "randomOrder": {1, 2, 3, 4, 5, 6, 7, 8, 9}, "duplicateElements": {1, 1, 2, 2, 3, 3, 4, 4}, "largeArray": {-1, -10000, -12345, -2032, -23, 0, 0, 0, 0, 10, 10000, 1024, 1024354, 155, 174, 1955, 2, 255, 3, 322, 4741, 96524}, "singleNegativeElement": {-7}, "arrayWithZeroes": {-2, 0, 0, 0, 3}, "ascendingOrder": {1, 2, 3, 4, 5}, "descendingOrderWithDuplicates": {1, 2, 3, 3, 4, 5, 5}, "boundaryValues": {-2147483647, 2147483648}, "mixedSignNumbers": {-2, -1, 0, 1, 2}, }, } func TestBubble(t *testing.T) { for testCase, array := range testData.ArrayList { t.Run(testCase, func(t *testing.T) { actual := Bubble(array) assert.ElementsMatch(t, actual, testData.ExpectedList[testCase]) }) } }
Bonus: Repositori Github yang melaksanakan logik yang dibentangkan dalam catatan blog ini boleh didapati di sini https://github.com/MedUnes/dsa-go. Setakat ini ia mengandungi tindakan Github yang menjalankan ujian ini dan juga menunjukkan lencana hijau yang sangat terkenal itu ;)
Jumpa anda dalam siaran bermaklumat seterusnya [semoga]!
Atas ialah kandungan terperinci Daripada PHPUnit ke Go: Ujian Unit Terpacu Data untuk Pembangun Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!