Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion tests/C0/UsernameValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,67 @@

namespace Tests\C0;

use App\UsernameValidation;
use PHPUnit\Framework\TestCase;

class UsernameValidationTest extends TestCase
{
// TODO: write 6 tests to coverage 100% code
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)))), 1, $length);
Copy link
Copy Markdown
Member

@tuanpt-0634 tuanpt-0634 Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Có cần phải hàm phức tạp này không em? Viết sao cho nó vừa đúng case, vừa đơn giản, vừa đảm bảo chạy nhanh

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Em thấy testcase nó cũng như class bình thường thôi ạ, viết sao cho nó thoải mái + reuse cao là được. Ngoài ra nữa thì hàm này sẽ suppỏt cho 1 case là nếu anh change MaxLength và MinLength thì nó vẫn đảm bảo là test case vẫn đúng. Ở đây em ko muốn người ta phải tập trung vào cách define hoặc config mà tập chung vào test thì nó sẽ oke hơn

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nếu anh viết test case như thế này thì có đơn giản hơn không :D

public function test_IT_not_pass_WHEN_value_exceed_maxlength() 
{
    $username = str_pad('a', UsernameValidation::MAX_LENGTH + 1, 'b');
    $validation = new UsernameValidation;

    $this->assertFalse($validation->isValid($username));
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

str_pad('a', UsernameValidation::MAX_LENGTH + 1, 'b');

Oke a, cái này em giờ mới biết dùng được kiểu này :v
để e sửa ạ

}

public function test_give_minimum_username_then_false_and_show_message()
{
$usernameValidation = new UsernameValidation();

$this->assertFalse($usernameValidation->isValid(''));
$this->assertEquals('Minimum length is ' . UsernameValidation::MIN_LENGTH, $usernameValidation->getMessage());
}

public function test_give_maximum_username_then_false_and_show_message()
{
$usernameValidation = new UsernameValidation();
$username = $this->generateRandomString(UsernameValidation::MAX_LENGTH + 1); //get string always greater then MAX_LENGTH

$this->assertFalse($usernameValidation->isValid($username));
$this->assertEquals('Maximum length is ' . UsernameValidation::MAX_LENGTH, $usernameValidation->getMessage());
}

public function test_username_have_dash_at_begin_or_end_then_false_and_show_message()
Copy link
Copy Markdown
Member

@tuanpt-0634 tuanpt-0634 Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So với cách đặt tên:

test_IT_not_pass_WHEN_value_has_dash_at_begining

Thì có dễ hiểu hơn không nhỉ? Ở đây IT là class under test => it not pass nghĩa là usernam validation not pass WHEN là điều kiện đầu vào

Khi dùng --testdox ta sẽ có message:

Username Validation (Tests\C0\UsernameValidation)
 ✔ IT not pass WHEN value exceed maxlength
 ✔ IT not pass WHEN value has dash at begining
 ✔ IT not pass WHEN value has multiple dashes

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tuanpt-0634
VIết như anh cũng được, nói chung tùy vào ngữ cảnh. Nhưng trên thực tế thì sử dụng từ pass hoặc từ it thì nó khá là ít ngữ cảnh để dùng và thực ra nó khá là chung chung. Cái ở đây em muốn mọi người nhìn vào có thể hiểu ngay lập tức function này test gì chứ ko phải là nhìn vào function xong nhìn thêm vào class nữa vì trong trường hợp 1 class nhiều case thì giả sử nhé số case xuống dòng vượt quá chiều cao của màn hình => anh phải khéo lên tìm cái class của nó để xem nó đang test cái gì...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass ở đây dùng cho class validation thôi, vì validation thì chỉ có pass hay failed. Còn anh đang muốn suggest chung 1 pattern đặt tên cho test, ko bắt buộc nhưng dễ follow lúc đầu. Ở đây anh nghĩ nên xem class là unit thay vì từng method, khi đó mình sẽ test hành vi của class thay vì test từng method, chẳng hạn có thay đổi tên method nhưng có thể không cần đặt lại tên test case, anh đúc kết từ bài này https://dzone.com/articles/7-popular-unit-test-naming

Should_ExpectedBehavior_When_StateUnderTest() {}
Should_ThrowException_When_AgeLessThan18() {}
Should_FailToWithdrawMoney_ForInvalidAccount() {}
Should_FailToAdmit_IfMandatoryFieldsAreMissing() {}

=>

public function test_it_expected_behavior_when_condition() {}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oki anh, thế thì mình nên tổng hợp lại rồi để đó là 1 convention ạ . Kiểu thế thì mọi người cũng dễ follow hơn

Copy link
Copy Markdown
Author

@namnhp-2137 namnhp-2137 Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anw nếu mọi người quen rồi thì đặt như thế nào cũng được mà a :))), Freestyle mà ✌️
Miễn sao nó thể hiện được tính chất là test gì ở đâu và kết quả như nào là ổn áp ạ :D

{
$usernameValidation = new UsernameValidation();
$username = $this->generateRandomString(floor(UsernameValidation::MAX_LENGTH / 2)); //get string allow in length
$username .= '-'; //add dash to test valid

$this->assertFalse($usernameValidation->isValid($username));
$this->assertEquals('- cannot appear at begin or end of name', $usernameValidation->getMessage());
}

public function test_username_have_multiple_dash_at_same_place_then_false_and_show_message()
{
$usernameValidation = new UsernameValidation();
$username = $this->generateRandomString(floor(UsernameValidation::MAX_LENGTH / 2)); //get string allow in length
$username .= '--'; //add multiple dash to test valid

$this->assertFalse($usernameValidation->isValid($username));
$this->assertEquals('Only single - is allowed', $usernameValidation->getMessage());
}

public function test_username_have_character_not_allow_then_false_and_show_message()
{
$usernameValidation = new UsernameValidation();
$username = $this->generateRandomString(floor(UsernameValidation::MAX_LENGTH / 2)); //get string allow in length
$username .= '@'; //add character not allow test valid

$this->assertFalse($usernameValidation->isValid($username));
$this->assertEquals('Invalid character. Use only letters, digits and -', $usernameValidation->getMessage());
}

public function test_username_id_valid()
{
$usernameValidation = new UsernameValidation();
$username = $this->generateRandomString(floor(UsernameValidation::MAX_LENGTH / 2)); //get string allow in length

$this->assertTrue($usernameValidation->isValid($username));
}
}