[英]How to handle a unit/integration test that contains too many lines of codes?
在我現在的公司,自 2014 年以來,我們有一個 web 應用程序正在 PHP 由 20 多個不同的開發人員開發。最近,我聽到我的團隊成員抱怨一些單元測試過於龐大(不可讀且不容易跟蹤內部代碼)而不是向測試 class 添加新的場景/方法,他們想創建新的測試類並將這些新場景/方法添加到新的場景/方法中。 假設我們有一個 class,如下所示:
<?php
class Foo {
public function getOne(): string
public function getAll(): array
public function validate(): bool
}
?>
我們有一個現有的單元測試 class 如下:
<?php
class FooTest {
public function testGetOne() {
// scenario 1
// scenerio 2
// scenario 3
// scenario 4
// scenario 5
// scenario 6
...
}
public function testGetAll() {
// scenario 1
// scenario 2
// scenario 3
...
}
public function testValidate() {
// scenario 1
// scenario 2
...
}
}
?>
正如您在上面看到的,我們正在遵循一些測試類指南:
我們相信它有利於可追溯性。 另一方面,有超過 1000 行的測試類,我們想以某種方式重構它們。 對我來說,要解決的問題是:
我想聽聽你的建議!
給你幾個更多的想法 -
1/ 您可以在擴展的 class 的新層中執行一些設置步驟 - 例如,這是我用來創建一些常規設置的更通用的測試父類之一,以及測試的代碼質量檢查代碼本身:
<?php
namespace Tests;
use PHPUnit\Framework\TestCase as PHPUnit_TestCase;
use PHPUnitGoodPractices\Traits as PHPUnitGoodPractices;
/**
* @SuppressWarnings(PHPMD.NumberOfChildren)
*/
abstract class TestCase extends PHPUnit_TestCase
{
use TestCaseTrait; // setup Mockery
use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use PHPUnitGoodPractices\ExpectationViaCodeOverAnnotationTrait;
use PHPUnitGoodPractices\ExpectOverSetExceptionTrait;
use PHPUnitGoodPractices\IdentityOverEqualityTrait;
#use PHPUnitGoodPractices\ProphecyOverMockObjectTrait;
}
我自己的許多測試將擴展Tests\TestCase
。
正如我在 class 中所使用的那樣,您還可以使用特征將通用功能移出各個測試類。 Soem DocBlock 注釋,例如@before ,也將以與protected function setUp(): void {}
等方法相同的方式運行代碼。
2/ @dataProvider可能更有用——它們返回一個數據數組(或從yield
Generator
方法中產生)。 如果您的測試針對不同數據的多個版本運行相同的測試代碼,則使用 DataProvider 方法允許使用測試方法的數據參數調用單個測試數十次,甚至數百次。
<?php
use PHPUnit\Framework\TestCase;
class DataTest extends TestCase
{
/**
* @dataProvider additionProvider
*/
public function testAdd($a, $b, $expected)
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider()
{
return [
[0, 0, 0],
[0, 1, 1],
[1, 0, 1],
[1, 1, 3], // this test would fail
];
}
}
1) - 我會說當你重構你的測試 class 時,你將擁有一個更干凈、更輕量級的 class,例如,我有一個包含 4000 多行代碼的 userTest class。 我構建測試文件夾的方式就是我的項目文件夾的設置方式。 因此,例如,如果我有 App/Repositories/UserRepository,那么我就會有 Tests/Repositories/UserTest。 它更干凈,我寧願不將我的測試分成不同的類。 因為其他開發者永遠不會明白其中的道理。
2) - 我建議使用此命名約定,MethodName_ExpectedBehavior_StateUnderTest, validate_should_throw_an_error_if_X_field_is_missing 或者您可以使用 PascalCase。 https://dzone.com/articles/7-popular-unit-test-naming
3) - 您始終可以將模擬和輔助方法封裝在單獨的 class 中,您可以靜態定義它們或使用測試 class 中的設置方法創建 class 的新實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.