Số cuộc gọi giả python

Plugin này cài đặt một bộ cố định mô phỏng là một trình bao bọc mỏng xung quanh API vá do gói mô phỏng cung cấp, nhưng với lợi ích là không phải lo lắng về việc hoàn tác các bản vá khi kết thúc thử nghiệm

Nếu bạn thấy thư viện này hữu ích, hãy đóng góp một số chu kỳ CPU cho nỗ lực phát triển của nó bằng cách nhấp vào bên trên. Cảm ơn bạn. 😇

Tại sao phải bận tâm với một plugin?

Có một số cách sử dụng bản vá khác nhau trong API giả tiêu chuẩn, nhưng IMHO chúng không mở rộng quy mô tốt khi bạn có nhiều hơn một hoặc hai bản vá để áp dụng

Nó có thể dẫn đến việc lồng quá nhiều câu lệnh with, phá vỡ quy trình của bài kiểm tra

import mock

def test_unix_fs():
    with mock.patch('os.remove'):
        UnixFS.rm('file')
        os.remove.assert_called_once_with('file')

        with mock.patch('os.listdir'):
            assert UnixFS.ls('dir') == expected
            # ...

    with mock.patch('shutil.copy'):
        UnixFS.cp('src', 'dst')
        # ...

Người ta có thể sử dụng bản vá làm công cụ trang trí để cải thiện quy trình kiểm tra

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...

Nhưng điều này gây ra một số nhược điểm

  • các chức năng kiểm tra phải nhận các đối tượng giả làm tham số, ngay cả khi bạn không định truy cập trực tiếp vào chúng;

  • nhận các bản mô phỏng dưới dạng tham số không kết hợp độc đáo với cách tiếp cận đặt tên đồ đạc dưới dạng tham số của pytest hoặc pytest. dấu. tham số hóa;

  • bạn không thể dễ dàng hoàn tác chế độ mô phỏng trong quá trình thực hiện thử nghiệm;

Lưu ý về cách sử dụng làm trình quản lý ngữ cảnh

Mặc dù API của mocker cố ý giống như mock. bản vá, việc sử dụng nó làm trình quản lý bối cảnh và trình trang trí chức năng không được hỗ trợ thông qua lịch thi đấu. Mục đích của plugin này là sử dụng trình quản lý bối cảnh và trình trang trí chức năng để chế nhạo không cần thiết. Thật vậy, cố gắng sử dụng chức năng trong mocker theo cách này có thể dẫn đến các lỗi không trực quan

def test_context_manager(mocker):
    a = A()
    with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
        assert a.doIt() == True
================================== FAILURES ===================================
____________________________ test_context_manager _____________________________
in test_context_manager
    with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
E   AttributeError: __exit__

Tuy nhiên, bạn có thể sử dụng mocker. mock_module để truy cập mô-đun giả bên dưới, e. g. để trả lại một trình quản lý bối cảnh trong một vật cố định tạm thời chế nhạo một cái gì đó

Chất lượng công việc là một trong những yếu tố quan trọng quyết định thành công của bạn tại nơi làm việc. Có nhiều cách để thực hiện điều này trong lĩnh vực công nghệ phần mềm. Nhưng có một cách dễ dàng và hiệu quả là áp dụng kiểm tra. Lý do đơn giản là khả năng viết mã đạt chất lượng thường quan trọng hơn nhiều so với việc viết một khối lượng lớn mã khó bảo trì và tồn tại nhiều lỗi

  04 Điều Cần Chú Ý Cho Người Mới Làm Kiểm thử tự động

  Hiệu quả của thử nghiệm với TDD trong Laravel

Kiểm tra đơn vị (Kiểm tra đơn vị) là kỹ thuật kiểm tra các khối thành phần nhỏ nhất trong phần mềm (thường là các hàm hoặc phương thức). Đây là một trong những cấp độ kiểm tra đơn giản và có thể bắt đầu sớm trong vòng đời phát triển phần mềm. Ngoài ra, bạn có thể viết bài kiểm tra đơn vị trước khi viết mã. Tuy nhiên, đây không phải là một thuật ngữ mới trong lĩnh vực phần mềm. Kiểm tra đơn vị khái niệm xuất hiện lần đầu trong ngôn ngữ lập trình Smalltalk vào những năm 1970. Đến nay, bài kiểm tra đơn vị gần như đã trở thành một tiêu chuẩn trong ngành theo mục tiêu của nó là phục vụ yêu cầu nâng cao chất lượng sản phẩm phần mềm

Số cuộc gọi giả python
Số cuộc gọi giả python

“Hành trình vạn dặm bắt đầu từ một bước chân. ” – Lão Tử

Với nhiều lập trình viên, dù mới vào nghề hay đã học giỏi, thì unit test là một trong những kỹ năng không thể thiếu khi đi làm. Nếu bạn chưa từng nghe qua hoặc chưa có điều kiện thực hiện thì hãy cùng bước những bước chân đầu tiên qua bài viết này nhé

Bài viết này có gì

Với bài viết này, bạn học được những nội dung sau

  • Một số khái niệm cơ bản trong hoạt động thử nghiệm và thử nghiệm đơn vị
  • Use JUnit in project Java said chung
  • Kết hợp Mockito và JUnit để thực hiện kiểm tra trong một số vấn đề thực tế
  • Case Study và những bài học khi thực hiện kiểm tra

Lợi ích của Unit Testing

  • Tách công việc kiểm tra với mã nguồn;
  • Duy trì một bộ kiểm tra liên tục được cập nhật
  • Mã bảo đảm mới không ảnh hưởng và gây ra lỗi cho các chức năng hiện có (thông qua việc thực hiện chạy lại toàn bộ bộ kiểm tra đã viết từ trước)

thuật ngữ

Để đọc hiểu nội dung hướng dẫn này, bạn cần biết đến một số thuật ngữ thông thường được sử dụng trong các hoạt động kiểm tra

trường hợp thử nghiệm

Trường hợp thử nghiệm là các trường hợp cần kiểm tra với đầu vào và đầu ra được xác định cụ thể. Một trường hợp thử nghiệm thường có hai thành phần dưới đây

  • Gia trị được ki vọng. Giá trị mà chúng ta mong chờ khối lệnh trả về
  • Giá trị thực. Giá trị thực tế mà khối lệnh trả lại

Sau khi thực hiện khối lệnh cần kiểm tra, chúng ta sẽ nhận được giá trị thực. Lấy giá trị đó để so sánh với giá trị dự kiến. Nếu hai giá trị này trùng khớp với nhau thì kết quả của trường hợp thử nghiệm là ĐẠT. Ngược lại, kết quả là FAIL

Ứng dụng (hoặc Mã) Đang thử nghiệm

Ứng dụng đang thử nghiệm (AUT) là thuật ngữ thông thường được sử dụng để chỉ đến hệ thống/ứng dụng đang được kiểm tra. Với kiểm tra đơn vị hoạt động, các đơn vị kiểm tra của chúng tôi là những thành phần nhỏ nhất trong hệ thống nên có thể sử dụng các thuật ngữ khác nhau phù hợp hơn như Code Under Test (CUT)

Mock và Stub

Đây là các thành phần bên ngoài được mô phỏng hoặc giả lập trong ngữ cảnh của hoạt động kiểm tra. Thông thường, để AUT hoạt động đúng chức năng thì cần đến những thành phần bên ngoài như Dịch vụ web, Cơ sở dữ liệu,… Ở cấp độ kiểm tra đơn vị, chúng ta cần phải tách rời các thành phần phụ thuộc này để có thể dễ dàng thực hiện . Phần này sẽ được giải thích rõ hơn trong mục Sử dụng Mockito (Mocking framework)

Lưu ý. Ngoài thuật ngữ mock và stub, xin giới thiệu bạn sẽ gặp các từ khác nhau như Spy và Fake

Thiết kế trường hợp thử nghiệm

Trong phần này, chúng ta sẽ tìm hiểu các loại test case, cấu trúc thường gặp ở test case và xem xét một số yếu tố cấu thành nên một test case tốt. Dựa vào các đặc điểm đó, chúng ta sẽ tìm hiểu các nguyên tắc để có thể thiết kế và thực hiện được các test case tốt

Phân loại test case

  1. Trường hợp thử nghiệm tích cực. Là những trường hợp kiểm tra để chắc chắn rằng người dùng có thể thực hiện được thao tác với dữ liệu hợp lệ
  2. Trường hợp thử nghiệm tiêu cực. Là những trường hợp kiểm tra tìm nguyên nhân gây lỗi cho ứng dụng bằng cách sử dụng dữ liệu không hợp lệ

Vui lòng xác định các loại trường hợp thử nghiệm trên một ví dụ đơn giản như sau. Giả sử, chúng ta đang thiết kế ứng dụng đặt phòng khách sạn và có một yêu cầu là

Hệ thống cho phép khách hàng có thể đặt phòng mới với thời gian xác định

Với yêu cầu trên, chúng ta có một số trường hợp cần kiểm tra như sau

  • Trường hợp hợp lệ là chắc chắn có thể bổ sung phòng với các dữ liệu hợp lệ như mã phòng cần đặt, thời gian hợp lệ, mã khách hàng hợp lệ, giá tiền được tính với số ngày đặt,…
  • Còn lại các trường hợp phủ định sẽ cố gắng thực hiện thao tác đặt phòng với những dữ liệu không hợp lệ như
  • Đặt phòng mới mà không có mã phòng
  • Đặt phòng mới với thời gian không hợp lệ (thời gian ở quá khứ)
  • Đặt phòng mới với mã khách hàng không tồn tại trong cơ sở dữ liệu
  • Đặt phòng mới với giá tiền âm (nhỏ hơn 0)
  • … and many other fields

Hy vọng qua ví dụ trên, bạn có thể phân loại các trường hợp thử nghiệm và xác định rõ ràng các trường hợp thử nghiệm cho yêu cầu phần mềm mà bạn đang thực hiện

Cấu hình một test case

Các mã cấu trúc mà chúng ta phải truy quét trong một trường hợp thử nghiệm là cấu trúc AAA. Cấu trúc này bao gồm 3 thành phần

  • Sắp xếp – Chuẩn bị dữ liệu đầu vào và các điều kiện khác để thực hiện test case
  • Hành động – Thực hiện công việc gọi phương thức/hàm với đầu vào đã được chuẩn bị ở Sắp xếp và nhận về kết quả thực tế
  • Assert – So sánh giá trị mong đợi và giá trị thực tế nhận được ở bước Act. Kết quả của test case sẽ là một trong hai trạng thái sau
  • VƯỢT QUA. if the results queue and results thực tế phù hợp với nhau
  • THẤT ​​BẠI. if results queues other than results with reality

Đôi khi bạn sẽ bắt gặp một số bài viết được sử dụng từ cấu trúc Cho-Khi-Thì. Về bản chất, cũng chính là cấu trúc AAA như trên

Thành phần cố định (Fixtures)

Là những phần được lặp lại thông qua từng trường hợp thử nghiệm và có thể chia sẻ các thao tác chung giữa các trường hợp thử nghiệm. Ví dụ. thiết lập cấu hình hoặc chuẩn bị dữ liệu trước khi bộ kiểm tra được thực thi và thu dọn bộ nhớ sau khi hoàn thành. Cố định phần thành phần phải được đặt trên cùng của cuộc kiểm tra

Có bốn loại thành phần cố định chính

Cài đặt

Is into the part is done before the test case thực thi. Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi bài kiểm tra đơn vị), chúng ta thường gặp các phương thức/hàm hoặc chú thích có tên là BeforeEach. This section is Setup

Cài đặt một lần

Là thành phần được thực hiện lần đầu tiên (trước khi cả thiết lập và trường hợp thử nghiệm được thực hiện). Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi bài kiểm tra đơn vị), chúng ta thường gặp các phương thức/hàm hoặc chú thích có tên là BeforeAll. Thành phần này chính là Thiết lập một lần

Phá bỏ

Thành phần được thực thi sau khi trường hợp thử nghiệm được thực thi. Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi bài kiểm tra đơn vị), chúng ta thường gặp các phương thức/hàm hoặc chú thích có tên là AfterEach. This section is Teardown

Rớt Một Lần

Là thành phần được thực thi sau cùng (sau khi tất cả test case và teardown được thực thi). Trong một số thư viện xUnit (công cụ hỗ trợ viết và thực thi bài kiểm tra đơn vị), chúng tôi thường gặp các phương thức/hàm hoặc chú thích có tên là AfterAll. Thành phần này chính là One-Time Teardown

Đặc tính của một bài kiểm tra đơn vị tốt

Một ca kiểm tra tốt sẽ có những đặc điểm sau đây

  • Quá trình viết – Có thể bao quát được nhiều trường hợp kiểm tra mà không mất quá nhiều công sức
  • Dễ đọc – Có thể mô tả chính xác hành vi hoặc chức năng đã được kiểm tra
  • Tự động hóa – Có thể thực hiện lặp lại nhiều lần
  • Thực thi nhanh và thực thi nhanh
  • Đồng nhất – Luôn trả về kết quả tương tự sau mỗi lần chạy (nếu không thay đổi mã nguồn bên trong)
  • Cô lập – Có thể thực thi độc lập mà không phụ thuộc vào các thành phần khác nhau trong hệ thống. Bạn có thể tham khảo mục “Sử dụng Mockito” để làm rõ hơn ý kiến ​​này
  • Khi kết quả kiểm tra thất bại (FAILED), có thể dễ dàng tìm ra giá trị mong đợi và nhanh chóng xác định được vấn đề

Quy định đặt tên

Kiểm tra tên lớp chứa mã kiểm tra

Tên lớp chứa mã kiểm tra thường sử dụng hậu tố “Kiểm tra” sau tên lớp được kiểm tra. Ví dụ. tên lớp là StockService thì tên lớp chứa mã kiểm tra sẽ là StockServiceTests

Kiểm tra tên phương thức kiểm tra (trường hợp thử nghiệm)

Theo nguyên tắc, tên phương thức kiểm tra phải giải thích nhiệm vụ rõ ràng. You can tham khảo một số quy định ướt đặt tên cho phương thức như sau

  1. Use from should. Ví dụ. cổ phiếu yêu thích Nên lưu, hôm nay Giá Nên hiển thị
@Test
public void favouriteStocksShouldbeSaved() {}
  1. Viết theo mẫu Given[Đầu-Vào]Khi[Hành-Vi]Thì[Kết-Quả-Mong-Đợi]. Ví dụ
@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
  1. Viết theo mẫu when[hành-vi]_then[Kết-quả]
@Test
public void whenEnterValidUsernameAndPassword_thenLoginSuccessfully() {}

Gợi ý viết kiểm tra tốt

  1. Mỗi trường hợp thử nghiệm phải là một phương thức độc lập, có thể thực thi mà không phụ thuộc vào bất kỳ trường hợp thử nghiệm nào khác
  2. Thứ tự thực hiện của mỗi trường hợp thử nghiệm không nên ảnh hưởng đến kết quả thực thi (mặc dù có thể)
  3. Khi phát hiện lỗi trong chương trình, hãy viết kiểm tra ngay cho trường hợp xảy ra lỗi đó để có thể kiểm tra lại sau này
  4. Kiểm tra tên phương thức phải rõ ràng. Vì vậy không phải làm dự kiến ​​nếu tên phương thức quá dài. Ví dụ TestDivision WhenNumPositiveDenomNegative tốt hơn DivisionTest3
  5. Vui lòng kiểm tra các trường hợp ném ngoại lệ (nếu có). Ví dụ WhenDivisionByZeroShouldThrowException
  6. Vui lòng kiểm tra các trường hợp phủ định để xác định biểu thức phản hồi khi đầu vào là dữ liệu không hợp lệ

Use JUnit

Hiện tại, JUnit đã được tích hợp và hỗ trợ phần lớn các IDE hiện có cho Java (như Eclipse, IntelliJ, NetBeans,…). Việc sử dụng JUnit trong các dự án Java không khó. Các bạn có thể tìm hiểu cách cài đặt thư viện cho dự án của mình thông qua các hướng dẫn trên mạng

Trong mục này, chúng ta sẽ giống như các tính năng được hỗ trợ trong JUnit 5 – phiên bản mới nhất hiện nay

ví dụ đầu tiên

Dưới đây là ví dụ giúp bạn có cái nhìn tổng quan về một bài kiểm tra được viết với JUnit5

import com.codegym.Calculator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatorTests {
    private final Calculator calculator = new Calculator();
    @Test
    void shouldReturn2When1Plus1() {
        assertEquals(2, calculator.add(1, 1));
    }
}

Giải thích ví dụ

  • @Test là chú thích Đánh dấu phương thức nênReturn2When1Plus1() là một trường hợp thử nghiệm. Xin lưu ý rằng tên của phương thức kiểm tra được viết rất rõ ràng là nên trả về kết quả 2 khi 1 cộng 1
  • Phần thân của phương thức chứa một dòng mã kiểm tra kết quả của phương thức add() với đầu vào là hai số có giá trị lần lượt là 1 và 1
  • So sánh giá trị thực tế được trả về của phương add() với giá trị mong đợi là 2
  • Sau khi chạy trường hợp thử nghiệm này, kết quả sẽ là PASS if phương thức add(1, 1)) trả về kết quả đúng bằng 2

Các mục tiếp theo sẽ cung cấp thêm chi tiết về một số tính năng cơ bản được hỗ trợ trong JUnit5

Các annotation trong JUnit

Sơ đồ dưới đây có thể hiển thị thứ tự thực hiện các phương thức khi được đánh dấu bằng chú thích tương ứng

Số cuộc gọi giả python
Số cuộc gọi giả python

Chú thích @B BeforeAll, @B BeforeEach,@afterEach, @afterAll là các thành phần cố định, thực hiện các chức năng lặp lại chức năng. Chú thích @Test được sử dụng để xác định một trường hợp thử nghiệm

khẳng định

Các xác nhận là lớp chứa các phương thức hỗ trợ Đánh giá các điều kiện trong quá trình kiểm tra

Vì vậy, với phiên bản trước, JUnit 5 vẫn giữ nguyên các phương thức cũ và bổ sung một số phương thức mới tận dụng các tích năng của Java 8

Dưới đây là danh sách các xác nhận phương thức có trong JUnit5

khẳng địnhTrue và khẳng địnhFalse

Phương thức assertTrue được sử dụng để kiểm tra kết quả của điều kiện có bằng đúng hay không. Ví dụ

________số 8

assertEquals và assertNotEquals

Phương thức assertEquals được sử dụng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Ví dụ

assertEquals và assertNotEquals
Phương thức assertEquals được dùng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Ví dụ:

Ngược lại, Phương thức assertNotEquals được sử dụng để kiểm tra giá trị mong đợi và thực tế có bằng nhau hay không. Chúng ta cập nhật lại ví dụ ở trên

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...
0

Với trường hợp các giá trị mà chúng ta so sánh thuộc kiểu Đối tượng, assertEquals và assertNotEquals sẽ gọi phương thức bằng để so sánh giá trị

Có một điểm cần lưu ý nếu giá trị là kiểu số thực (float or double). Trên thực tế, có nhiều trường hợp mà giá trị thực được mong đợi và thực tế có thể chênh lệch với nhau trong khoảng chấp nhận được. Với tình huống này, phương thức assertEquals và assertNotEquals giúp tham số thứ ba là delta (bên cạnh mong đợi và thực tế). Chúng ta cùng xem qua ví dụ dưới đây

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...
1

Kết quả được phép chia 12 cho 3. 001 then will be a number of 3. 9998667. Kết quả của cuộc kiểm tra ví dụ trên đã được THÔNG QUA vì chúng ta đã cho phép độ chênh lệch tối đa là 0. 001

khẳng địnhArrayEquals

Phương thức assertArrayEquals có thể xác nhận mảng mong đợi và thực tế có bằng nhau hay không. Chúng ta cùng xem xét ví dụ dưới đây

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...
2

khẳng địnhSame và khẳng địnhNotSame

Chúng ta muốn xác nhận giá trị mong đợi và tham chiếu thực tế đến cùng một đối tượng hay không, chúng ta phải sử dụng assertSame hoặc assertNotSame

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...
3

Kết quả của bài kiểm tra phương thức trên là KHÔNG THÀNH CÔNG vì hai biến thực tế và dự kiến đang tham chiếu đến hai đối tượng khác nhau trong bộ nhớ

Chúng ta nên lưu ý về sự khác nhau giữa assertSame và assertEquals (đã tìm hiểu ở ví dụ trước)

  • assertEquals chỉ quan tâm đến giá trị có bằng nhau không (thông qua phương thức bằng) mà không cần biết hai giá trị được so sánh phải giống nhau là một đối tượng hay không
  • assertSame sẽ trả về PASSED chỉ khi cả hai biến cùng tham chiếu đến một đối tượng

khẳng địnhIterableEquals

assertIterableEquals so sánh các giá trị được chứa bên trong hai đối tượng kiểu Iterable. To return results PASSED, two iterable must pay return by number of phantal, value of that parts and both position of the other section. Hãy cùng xem ví dụ dưới đây

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
0

Kết quả của test case on PASSED. Phương thức assertIterableEquals chỉ so sánh giá trị của các phần tử bên trong mà không quan tâm đến việc các phần tử này đang được lưu trữ tại hai biến thuộc kiểu khác nhau (ArrayList và LinkedList)

khẳng địnhNém

Để có thể xác nhận phương thức đang được kiểm tra có thể ném ra một ngoại lệ hay không, chúng ta có thể sử dụng assertThrows. Giả sử chúng ta có một phương thức như sau

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
1

Sử dụng cách thức dưới đây để kiểm tra xem phương thức throwAnExcepint() có ném ra một ngoại lệ hay không, và ngoại lệ đó phải là IllegalArgumentException hay không

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
2

Các khẳng định khác nhau

  • khẳng địnhLinesMatch
  • Thất bại
  • khẳng địnhNotNull và khẳng địnhNull
  • khẳng địnhTất cả
  • assertTimeout và assertTimeoutPreemptively

Sử dụng Mockito (Mocking framework)

Khi xây dựng phần mềm, AUT sẽ phụ thuộc vào các thành phần bên ngoài như cơ sở dữ liệu, API, tệp hệ thống,… Các thành phần phụ thuộc này có thể chưa có sẵn hoặc thậm chí chưa tồn tại tại thời điểm chúng tôi sử dụng. . Ngay cả khi các thành phần này đã được chuẩn bị sẵn sàng, thì việc thực hiện một trường hợp thử nghiệm có phụ thuộc sẽ chậm hơn vì phải cần thời gian chờ đợi và tương tác với các thành phần bên ngoài

Số cuộc gọi giả python
Số cuộc gọi giả python

Cô lập AUT là một trong những kỹ thuật giúp giải quyết vấn đề trên. Và lúc này, chúng ta sẽ cần đến các khung mô phỏng (tạm dịch là khung mô phỏng) để giả lập các thành phần bên ngoài, nhờ đó có thể cô lập và kiểm tra AUT dễ dàng hơn. Đối tượng mô phỏng này sẽ không gây phá vỡ cấu trúc mã nguồn khi đối tượng thực được thiết kế và triển khai. Hình dưới đây có thể thực hiện việc tạo hai đối tượng mô phỏng là Mock WS và Mock DB để thay thế sự phụ thuộc vào WebService và Database

Số cuộc gọi giả python
Số cuộc gọi giả python

Việc tìm hiểu cách thiết lập và sử dụng các mocking framework này là bước quan trọng giúp mở rộng Unit Test cho các hệ thống lớn và phức tạp. Với lập trình viên Java, Mockito là một công cụ không thể thiếu

Tạo đối tượng mô phỏng

Phương thức mock() cho phép chúng ta tạo đối tượng mô phỏng từ một lớp hoặc giao diện. Phương thức này không yêu cầu thêm gì khi sử dụng. Và nó có thể tạo các lớp mô phỏng thuộc tính hoặc các đối tượng mô phỏng cần sử dụng trong phương thức. Ví dụ dưới đây có thể hiện cách tạo một đối tượng mô phỏng kiểu UserRepository (đã được định nghĩa trước đó)

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
3

Mô phỏng hành động vi

Sử dụng phương thức khi() để mô phỏng hành vi của đối tượng. Để xác định kết quả thực hiện, chúng ta có thể sử dụng thenReturn() or thenThrow()

  • thenReturn() trả về kết quả
  • thenThrow() sẽ ném ra một ngoại lệ
@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
3

Nếu muốn trả lại nhiều kết quả cho nhiều lần gọi, chúng ta sẽ sử dụng thenReturn() nhiều lần như sau;

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
5

kiểm chứng

Chúng ta có thể kiểm tra xem phương thức/hàm có được gọi hay không thông qua phương thức xác minh()

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
3

Mockito hỗ trợ những tham số giúp chúng ta có thể mở rộng khả năng kiểm tra việc gọi phương thức như

  • Number ofcalls with times()
  • Thời gian thực hiện với thời gian chờ (), giúp kiểm tra thời gian thực hiện thuật toán có yêu cầu chắc chắn

Ví dụ

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
7

Kết hợp JUnit

Đây là đoạn mã ví dụ cách kết hợp Mockito và JUnit để viết mã kiểm tra đơn vị

@Test
public void GivenNullUsernameWhenCreateStudentThenShouldThrowException() {}
8

Ở phương thức trên, chúng ta mô phỏng hành vi lấy lượng người dùng thông qua phương thức count() được định nghĩa trong UserRepository. Khi count() được gọi, đối tượng mô phỏng sẽ trả về kết quả là 111 thay vì phải truy vấn vào cơ sở dữ liệu để lấy thông tin

nghiên cứu điển hình

Dự án mà chúng ta sẽ thực hiện là một trang cửa hàng trực tuyến đơn giản hỗ trợ duyệt danh sách sản phẩm và thông tin chi tiết của từng mặt hàng. Khách hàng có thể chọn sản phẩm và lưu vào giỏ hàng để thanh toán

Trước khi thực hiện việc viết mã, hãy thiết kế chi tiết bao gồm các giao diện, lớp và các phương thức có thể cần để thực hiện ứng dụng này. dựa vào bản thiết kế, hãy viết các trường hợp thử nghiệm đơn vị cho ứng dụng

Chặn đường tiếp theo

Cảm ơn bạn đã đồng hành cùng bài viết đến đây. Hy vọng những bước chân đầu tiên này sẽ mang lại nhiều ý nghĩa cho con đường học hỏi tiếp theo của bạn. Hãy tìm ngăn nắp và thực hiện hành động nhiều hơn để có thể làm chủ được kỹ năng Unit Test nói riêng và kiểm thử tự động nói chung. Đến đây, chúng ta nên làm gì để học và thực hiện hiệu quả hơn ở kỹ năng này?

Câu châm ngôn của mình là “Thế giới này thật là rộng lớn. and has too many books to read”. Nên nhắc đầu tiên luôn là đọc những cuốn sách đầu tiên hay về Unit Test, Test-Driven Development và những chủ đề liên quan. Các bạn xem qua gợi ý sách và trang web bên dưới nhé