× Giới thiệu Lịch khai giảng Tin tức Sản phẩm học viên

Kiểm thử phần mềm tự động với Python

25/10/2023 01:29

Trong bài viết này, chúng ta sẽ thảo luận về một số phương pháp kiểm thử phần mềm tự động bằng Python. 

Kiểm thử phần mềm là quá trình trong đó nhà phát triển đảm bảo rằng đầu ra thực tế của phần mềm phù hợp với đầu ra mong muốn bằng cách cung cấp một số đầu vào thử nghiệm cho phần mềm. Kiểm thử phần mềm là một bước quan trọng vì nếu được thực hiện đúng cách, nó có thể giúp nhà phát triển tìm ra lỗi trong phần mềm trong khoảng thời gian rất ngắn. Kiểm thử phần mềm có thể được chia thành hai loại, Kiểm thử thủ công và Kiểm thử tự động . Kiểm thử tự động là việc thực hiện kiểm thử bằng cách sử dụng tập lệnh thay vì con người. Trong bài viết này, chúng ta sẽ thảo luận về một số phương pháp kiểm thử phần mềm tự động bằng Python. Hãy viết một ứng dụng đơn giản để chúng ta thực hiện tất cả các bài kiểm tra. 

 
class Square:
    def __init__(self, side):
        """ creates a square having the given side
        """
        self.side = side
 
    def area(self):
        """ returns area of the square
        """
        return self.side**2
 
    def perimeter(self):
        """ returns perimeter of the square
        """
        return 4 * self.side
 
    def __repr__(self):
        """ declares how a Square object should be printed
        """
        s = 'Square with side = ' + str(self.side) + '\n' + \
        'Area = ' + str(self.area()) + '\n' + \
        'Perimeter = ' + str(self.perimeter())
        return s
 
 
if __name__ == '__main__':
    # read input from the user
    side = int(input('enter the side length to create a Square: '))
     
    # create a square with the provided side
    square = Square(side)
 
    # print the created square
    print(square)

Lưu ý: Để biết thêm thông tin về hàm __repr__(), hãy tham khảo bài viết này . Bây giờ chúng ta đã có phần mềm sẵn sàng, hãy xem cấu trúc thư mục của thư mục dự án và sau đó, chúng ta sẽ bắt đầu thử nghiệm phần mềm của mình.

---Software_Testing 
   |--- __init__.py (để khởi tạo thư mục dưới dạng gói python) 
   |--- app.py (phần mềm của chúng tôi) 
   |--- test (thư mục để giữ tất cả các tệp kiểm tra) 
           |--- __init__. py

Mô-đun 'unittest'

Một trong những vấn đề chính của kiểm thử thủ công là nó đòi hỏi thời gian và công sức. Trong thử nghiệm thủ công, chúng tôi kiểm tra ứng dụng qua một số đầu vào, nếu nó không thành công, chúng tôi sẽ ghi lại hoặc gỡ lỗi ứng dụng cho đầu vào thử nghiệm cụ thể đó, sau đó chúng tôi lặp lại quy trình. Với unittest , tất cả đầu vào kiểm tra có thể được cung cấp cùng một lúc và sau đó bạn có thể kiểm tra ứng dụng của mình. Cuối cùng, bạn nhận được một báo cáo chi tiết với tất cả các trường hợp kiểm thử thất bại được chỉ định rõ ràng, nếu có. Mô-đun unittest có cả khung thử nghiệm tích hợp và trình chạy thử nghiệm. Khung kiểm thử là một bộ quy tắc phải tuân theo khi viết các trường hợp kiểm thử, trong khi trình chạy kiểm thử là một công cụ thực hiện các kiểm thử này với một loạt cài đặt và thu thập kết quả. Cài đặt: unittest có sẵn tại PyPI và có thể được cài đặt bằng lệnh sau –

cài đặt pip không đáng tin cậy nhất

Sử dụng: Chúng tôi viết các bài kiểm tra trong mô-đun Python (.py). Để chạy thử nghiệm, chúng tôi chỉ cần thực thi mô-đun thử nghiệm bằng bất kỳ IDE hoặc thiết bị đầu cuối nào. Bây giờ, hãy viết một số bài kiểm tra cho phần mềm nhỏ của chúng ta đã thảo luận ở trên bằng cách sử dụng mô-đun nhỏ nhất.

 
  1. Tạo một tệp có tên test.py trong thư mục có tên “tests”.
  2. Trong test.py nhập unittest.
  3. Tạo một lớp có tên TestClass kế thừa từ lớp unittest.TestCase. Quy tắc 1: Tất cả các bài kiểm tra được viết dưới dạng các phương thức của một lớp, phải kế thừa từ lớp unittest.TestCase.
  4. Tạo một phương pháp thử nghiệm như dưới đây. Quy tắc 2: Tên của mỗi phương thức kiểm tra phải bắt đầu bằng “kiểm tra”, nếu không người chạy thử sẽ bỏ qua. 

 

 

 

def test_area(self):
    # testing the method Square.area().
     
    sq = Square(2)    # creates a Square of side 2 units.
 
    # test if the area of the above square is 4 units,
    # display an error message if it's not.
 
    self.assertEqual(sq.area(), 4,
        f'Area is shown {sq.area()} for side = {sq.side} units')
  1. Quy tắc 3: Chúng tôi sử dụng các câu lệnh khẳng định Equal() đặc biệt thay vì các câu lệnh khẳng định có sẵn trong Python. Đối số đầu tiên của khẳng địnhEqual() là đầu ra thực tế, đối số thứ hai là đầu ra mong muốn và đối số thứ ba là thông báo lỗi sẽ được hiển thị trong trường hợp hai giá trị khác nhau (kiểm tra thất bại).
  2. Để chạy thử nghiệm mà chúng ta vừa xác định, chúng ta cần gọi phương thức unittest.main(), thêm các dòng sau vào mô-đun “tests.py”. 

 

 

 

if __name__ == '__main__':
    unittest.main()
  1. Do những dòng này, ngay khi bạn chạy tập lệnh “test.py”, hàm unittest.main() sẽ được gọi và tất cả các bài kiểm tra sẽ được thực thi.

Cuối cùng, mô-đun “tests.py” sẽ giống với mã được đưa ra bên dưới. 

 

 

 

import unittest
from .. import app
 
class TestSum(unittest.TestCase):
 
    def test_area(self):
        sq = app.Square(2)
 
        self.assertEqual(sq.area(), 4,
            f'Area is shown {sq.area()} rather than 9')
 
if __name__ == '__main__':
    unittest.main()

Sau khi viết các trường hợp thử nghiệm, bây giờ chúng ta hãy kiểm tra ứng dụng của mình xem có lỗi nào không. Để kiểm tra ứng dụng của bạn, bạn chỉ cần thực thi tệp kiểm tra “tests.py” bằng cách sử dụng dấu nhắc lệnh hoặc bất kỳ IDE nào bạn chọn. Đầu ra sẽ giống như thế này.

. 
-------------------------------------------------- -------------------- 
Chạy 1 bài kiểm tra trong 0,000 giây 

OK

Trong dòng đầu tiên, .(dot) biểu thị một thử nghiệm thành công trong khi chữ 'F' sẽ biểu thị một trường hợp thử nghiệm thất bại. Cuối cùng, thông báo OK cho chúng ta biết rằng tất cả các bài kiểm tra đã được vượt qua thành công. Hãy thêm một vài thử nghiệm nữa trong “tests.py” và thử nghiệm lại ứng dụng của chúng tôi. 

 

 

 

import unittest
from .. import app
 
class TestSum(unittest.TestCase):
 
    def test_area(self):
        sq = app.Square(2)
        self.assertEqual(sq.area(), 4,
            f'Area is shown {sq.area()} rather than 9')
 
    def test_area_negative(self):
        sq = app.Square(-3)
        self.assertEqual(sq.area(), -1,
            f'Area is shown {sq.area()} rather than -1')
 
    def test_perimeter(self):
        sq = app.Square(5)
        self.assertEqual(sq.perimeter(), 20,
            f'Perimeter is {sq.perimeter()} rather than 20')
 
    def test_perimeter_negative(self):
        sq = app.Square(-6)
        self.assertEqual(sq.perimeter(), -1,
            f'Perimeter is {sq.perimeter()} rather than -1')
 
if __name__ == '__main__':
    unittest.main()
.FF 
==================================================== ======================== 
THẤT BẠI: test_area_ Negative (__main__.TestSum) 
-------------------- -------------------------------------------------- 
TracBack (cuộc gọi gần đây nhất gần đây nhất): 
  Tệp "tests_unittest.py", dòng 11, trong test_area_ Negative 
    self.assertEqual(sq.area(), -1, f'Area được hiển thị {sq.area()} thay vì -1 cho độ dài cạnh âm') 
AssertionError: 9 != -1 : Diện tích được hiển thị 9 thay vì -1 cho độ dài cạnh âm 

=========================== =============================================== 
THẤT BẠI: test_perimeter_ Negative (__main__ .TestSum) 
----------------------------------------------- -------------- 
TracBack (cuộc gọi gần đây nhất gần đây nhất): 
  Tệp "tests_unittest.py", dòng 19, trong test_perimeter_ Negative 
    self.assertEqual(sq.perimeter (), -1, f'Chu vi là {sq.perimeter()} thay vì -1 cho độ dài cạnh âm') 
AssertionError: -24 != -1 : Chu vi là -24 thay vì -1 cho độ dài cạnh âm 

-- -------------------------------------------------- ------------------ 
Chạy 4 bài kiểm tra trong 0,001 giây 

THẤT BẠI (thất bại=2)

Một số điều cần lưu ý trong báo cáo thử nghiệm ở trên là –

  • Dòng đầu tiên biểu thị rằng thử nghiệm 1 và thử nghiệm 3 được thực hiện thành công trong khi thử nghiệm 2 và thử nghiệm 4 không thành công
  • Mỗi trường hợp kiểm thử thất bại được mô tả trong báo cáo, dòng đầu tiên của mô tả chứa tên của trường hợp kiểm thử không thành công và dòng cuối cùng chứa thông báo lỗi mà chúng tôi đã xác định cho trường hợp kiểm thử đó.
  • Ở cuối báo cáo, bạn có thể thấy số lần kiểm tra thất bại, nếu không có bài kiểm tra nào thất bại, báo cáo sẽ kết thúc bằng OK

Lưu ý: Để biết thêm kiến ​​thức, bạn có thể đọc tài liệu đầy đủ về unittest .

Mô-đun “mũi2”

Mục đích của mũi2 là mở rộng unittest để giúp việc kiểm tra dễ dàng hơn. mũi2 tương thích với các bài kiểm tra được viết bằng khung kiểm tra unittest và có thể được sử dụng để thay thế cho trình chạy thử nghiệm unittest. Cài đặt: mũi2 có thể được cài đặt từ PyPI bằng lệnh,

pip cài đặt mũi2

Sử dụng: mũi2 không có bất kỳ khung thử nghiệm nào và chỉ đơn thuần là một trình chạy thử nghiệm tương thích với khung thử nghiệm nhỏ nhất. Vì vậy, chúng tôi sẽ chạy các bài kiểm tra tương tự mà chúng tôi đã viết ở trên (đối với unittest) bằng cách sử dụng mũi2. Để chạy thử nghiệm, chúng tôi sử dụng lệnh sau trong thư mục nguồn dự án (“Software_Testing” trong trường hợp của chúng tôi),

mũi2

Trong thuật ngữ của mũi2, tất cả các mô-đun python (.py) có tên bắt đầu từ “test” (tức là test_file.py, test_1.py) đều được coi là tệp thử nghiệm. Khi thực thi, mũi2 sẽ tìm kiếm tất cả các tệp kiểm tra trong tất cả các thư mục con nằm trong một hoặc nhiều danh mục sau,

  • là các gói python (chứa “__init__.py”).
  • có tên bắt đầu bằng “test” sau khi được viết thường, tức là TestFiles, test.
  • được đặt tên là “src” hoặc “lib”.

Đầu tiên, mũi2 tải tất cả các tệp thử nghiệm có trong dự án và sau đó các thử nghiệm được thực hiện. Do đó, với mũi2, chúng ta có thể tự do phân chia các bài kiểm tra của mình thành các tệp kiểm tra khác nhau trong các thư mục khác nhau và thực hiện chúng cùng một lúc, điều này rất hữu ích khi xử lý số lượng lớn các bài kiểm tra. Bây giờ chúng ta hãy tìm hiểu về các tùy chọn tùy chỉnh khác nhau do mũi2 cung cấp có thể giúp ích cho chúng ta trong quá trình thử nghiệm.

  1. Thay đổi thư mục tìm kiếm – Nếu chúng ta muốn thay đổi thư mục mà mũi2 tìm kiếm các tệp kiểm tra, chúng ta có thể thực hiện điều đó bằng cách sử dụng các đối số dòng lệnh -s hoặc –start-dir như,
mũi2 -s DIR_ADD DIR_NAME
  1. ở đây, DIR_NAME là thư mục mà chúng tôi muốn tìm kiếm các tệp kiểm tra và DIR_ADD là địa chỉ của thư mục mẹ của DIR_NAME so với thư mục nguồn dự án (tức là sử dụng “./” nếu thư mục kiểm tra nằm trong thư mục nguồn dự án chính nó). Điều này cực kỳ hữu ích khi bạn chỉ muốn kiểm tra một tính năng của ứng dụng tại một thời điểm.
  2. Chạy các trường hợp kiểm thử cụ thể – Sử dụng mũi2, chúng ta cũng có thể chạy một kiểm thử cụ thể tại một thời điểm bằng cách sử dụng các đối số dòng lệnh -s và –start-dir như,
mũi2 -s DIR_ADD DIR_NAME.TEST_FILE.TEST_CLASS.TEST_NAME
  • TEST_NAME: tên của phương pháp thử nghiệm.
  • TEST_CLASS: lớp trong đó phương thức kiểm tra được xác định.
  • TEST_FILE: tên của tệp thử nghiệm trong đó trường hợp thử nghiệm được xác định, tức là test.py.
  • DIR_NAME: thư mục chứa file test.
  • DIR_ADD: địa chỉ thư mục mẹ của DIR_NAME so với nguồn dự án.
  1. Chạy thử nghiệm trong một mô-đun duy nhất – mũi2 cũng có thể được sử dụng giống như unittest bằng cách gọi hàm chest2.main() giống như chúng ta đã gọi unittest.main() trong các ví dụ trước.

Mô-đun “pytest”

pytest là khung thử nghiệm phổ biến nhất cho python. Sử dụng pytest, bạn có thể kiểm tra mọi thứ từ tập lệnh python cơ bản đến cơ sở dữ liệu, API và giao diện người dùng. Mặc dù pytest chủ yếu được sử dụng để kiểm tra API nhưng trong bài viết này chúng tôi sẽ chỉ đề cập đến những điều cơ bản về pytest. Cài đặt: Bạn có thể cài đặt pytest từ PyPI bằng lệnh,

pip cài đặt pytest

Sử dụng: Trình chạy thử nghiệm pytest được gọi bằng lệnh sau trong nguồn dự án,

py.test

Không giống như mũi2, pytest tìm kiếm các tệp thử nghiệm ở tất cả các vị trí bên trong thư mục dự án. Bất kỳ tệp nào có tên bắt đầu bằng “test_” hoặc kết thúc bằng “_test” đều được coi là tệp thử nghiệm theo thuật ngữ pytest. Hãy tạo một tệp “test_file1.py” trong thư mục “tests” làm tệp thử nghiệm của chúng tôi. Tạo các phương thức kiểm thử: pytest hỗ trợ các phương thức kiểm thử được viết trong framework unittest, nhưng pytest framework cung cấp cú pháp dễ dàng hơn để viết các bài kiểm thử. Xem mã bên dưới để hiểu cú pháp phương pháp thử nghiệm của khung pytest. 

 

 

 

from .. import app
 
def test_file1_area():
    sq = app.Square(2)
    assert sq.area() == 4,
        f"area for side {sq.side} units is {sq.area()}"
 
def test_file1_perimeter():
    sq = app.Square(-1)
    assert sq.perimeter() == -1,
        f'perimeter is shown {sq.perimeter()} rather than -1'

Lưu ý: tương tự như unittest, pytest yêu cầu tất cả tên thử nghiệm phải bắt đầu bằng “test”. Không giống như unittest, pytest sử dụng các câu lệnh xác nhận python mặc định giúp sử dụng dễ dàng hơn. Lưu ý rằng, bây giờ thư mục “tests” chứa hai tệp là “tests.py” (được viết bằng unittest framework) và “test_file1.py” (được viết bằng pytest framework). Bây giờ hãy chạy thử nghiệm chạy thử nghiệm pytest.

py.test

Bạn sẽ nhận được một báo cáo tương tự như thu được bằng cách sử dụng unittest.

============================== Buổi kiểm tra bắt đầu ==================== ============ 
nền tảng linux -- Python 3.6.7, pytest-4.4.1, py-1.8.0, pluggy-0.9.0 
rootdir: /home/manthan/articles/Software_testing_in_Python đã thu thập 6 mục                                                               
kiểm tra/test_file1.py .F [ 33%] 
kiểm tra/test_file2.py .FF [100%] 
============================== ======== THẤT BẠI =======================================


Tỷ lệ phần trăm ở phía bên phải của báo cáo hiển thị tỷ lệ phần trăm thử nghiệm đã được hoàn thành tại thời điểm đó, tức là 2 trong số 6 trường hợp thử nghiệm đã được hoàn thành ở cuối “test_file1.py”. Dưới đây là một số tùy chỉnh cơ bản hơn đi kèm với pytest.

  1. Chạy các tệp kiểm tra cụ thể: Để chỉ chạy một tệp kiểm tra cụ thể, hãy sử dụng lệnh,
py.test <tên tệp>
  1. Khớp chuỗi con: Giả sử chúng ta chỉ muốn kiểm tra phương thức Area() của lớp Square, chúng ta có thể thực hiện việc này bằng cách sử dụng khớp chuỗi con như sau,
py.test -k "khu vực"
  1. Với lệnh này, pytest sẽ chỉ thực hiện những thử nghiệm có chuỗi “area” trong tên của chúng, tức là “test_file1_area()”, “test_area()”, v.v.
  2. Đánh dấu: Để thay thế cho việc so khớp chuỗi con, đánh dấu là một phương pháp khác sử dụng mà chúng ta có thể chạy một bộ thử nghiệm cụ thể. Trong phương pháp này, chúng tôi đánh dấu các bài kiểm tra mà chúng tôi muốn chạy. Quan sát ví dụ mã được đưa ra dưới đây, 

 

 

 

# @pytest.mark.<tag_name>
@pytest.mark.area    
 
def test_file1_area():
    sq = app.Square(2)
    assert sq.area() == 4,
        f"area for side {sq.side} units is {sq.area()}"
  1. Trong ví dụ mã trên test_file1_area() được đánh dấu bằng thẻ “khu vực”. Tất cả các phương pháp kiểm tra đã được đánh dấu bằng một số thẻ có thể được thực thi bằng cách sử dụng lệnh,
py.test -m <tag_name>
  1. Xử lý song song: Nếu bạn có số lượng lớn thử nghiệm thì pytest có thể được tùy chỉnh để chạy song song các phương pháp thử nghiệm này. Để làm được điều đó, bạn cần cài đặt pytest-xdist có thể được cài đặt bằng lệnh,
pip cài đặt pytest-xdist