Hướng dẫn unittest report python - trăn báo cáo mới nhất

Các bạn có bao giờ tái cấu trúc code không ? Sau mỗi lần refactor, bạn có bao giờ nín thở khi deploy lại sản phẩm lên PRODUCTION hay không? Làm thế nào để không phải trải qua cảm giác kinh hoàng ấy? Trong quy trình phát triển phần mềm, có một giai đoạn mà các lập trình có thể tự cứu được "sự nghiệp" của mình mà không phải chờ đợi kết quả test của các tester hay báo cáo vận hành sản phẩm trên PRODUCTION, giai đoạn đó là viết unit-test.

Vậy unit-test là gì ? Và áp dụng nó trong các bài toán giải quyết trong Python như thế nào? Mời các bạn theo dõi trong bài viết tiếp theo của tôi.

1. Unit-test là gì ?

Unit là một khái niệm trong hệ thống phần mềm và mỗi unit được định nghĩa là các thành phần độc lập với nhau theo "định cỡ": Function -> Class -> Module -> Package (với Python).Unit-test là một thuật ngữ trong kiểm thử phần mềm, được định nghĩa là kiểm thử mức đơn vị. Có nghĩa là đặt các bài test vào các thành phần "đơn vị" (unit) của hệ thống phần mềm.
Unit-test là một thuật ngữ trong kiểm thử phần mềm, được định nghĩa là kiểm thử mức đơn vị. Có nghĩa là đặt các bài test vào các thành phần "đơn vị" (unit) của hệ thống phần mềm.

Chúng ta có thể hiểu unit-test như một black-box-testing với tập dữ liệu đầu vào sau khi chạy qua một unit và tập dữ liệu đầu ra phải khớp với một tập dữ liệu đã được tính toán trước.

2. Ai là người viết unit-test?

Thông thường thì các lập trình viên là người sẽ phải chịu trách nhiệm viết unit-test. Vì unit-test là công cụ bảo đảm tính "đúng đắn" của mỗi thành phần sản phẩm mà họ làm ra.

Để có thể viết được các unit-test, các lập trình viên sẽ phải hiểu rõ về yêu cầu cần thực hiện trong các unit.

3. Khi nào thì viết unit-test?

Tùy vào đặc thù của từng dự án hoặc yêu cầu tiến độ của dự án mà lập trình viên sẽ thực hiện viết prototype cho unit-test trước cùng với các unit có thể xuất hiện trong hệ thống. Sau đó, trong lúc lập trình hoặc thậm chí là sau khi sản phẩm chạy ổn định rồi họ mới thực hiện viết unit-test (lúc này đã có các tập hợp dữ liệu input-output hoàn chỉnh).

4. Một số yêu cầu với unit-test.

  • Unit-test phải ngắn gọn, dễ hiểu, dễ đọc, có thể sẽ phải có đầy đủ mô tả cho từng nhóm dữ liệu input/output.
  • Mỗi unit-test cần phát triển riêng biệt, không nên thiết kế output của unit-test này là input của unit-test tiếp theo.
  • Khi đặt tên unit-test cần đặt tên gợi nhớ hoặc theo quy chuẩn của từng nhóm phát triển để tường minh việc unit-test này đang test cho unit nào.
  • Mỗi unit-test chỉ nên thực hiện test cho một unit, nếu các unit có về input/output hoặc code thì chấp nhận việc duplicate các unit-test.

5. Lợi ích của unit-test.

  • Khi có unit-test, các lập trình viên có thể tự tin mà refactor code.
  • Khi thực hiện chạy unit-test, đôi khi lập trình viên sẽ phát hiện ra lỗi tiềm ẩn (lỗi truy vấn đến database chẳng hạn).
  • Nếu làm việc cộng tác trong team, việc đặt unit-test như các rule trong tiến trình CI sẽ ngăn được trường hợp sản phẩm bị nhưng vẫn được triển khai trên PRODUCTION.

Cách sử dụng unit test trong Python.

Với mỗi ngôn ngữ lập trình lại có các công cụ, thư viện khác nhau để thực hiện viết unit-test. Trong Python, có thể sử dụng pytest và unittest để viết các unit-test. Do unittest có độ thông dụng nhiều hơn nên bài viết sau đây của tôi sẽ tập trung vào module unittest trong Python.

1. Giới thiệu về unittest.

Trong lập trình thì cách giới thiệu nhanh nhất cho một module/thư viện chính là ... lập trình dựa trên các đặc tính của module/thư viên đó. Sau đây là một ví dụ nhỏ về unitest. Các bạn hãy tạo một file có tên simple_unittest.py và gõ vào đoạn code như dưới đây.

# test_simple_unittest.py
import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('python'.upper(), 'PYTHON')

    def test_isupper(self):
        self.assertTrue('PYTHON'.isupper())
        self.assertFalse('Python'.isupper())

    def test_islower(self):
        self.assertTrue('PYTHON'.islower())
        self.assertFalse('Python'.islower())

    def test_split(self):
        test_string = 'python is a best language'
        self.assertEqual(test_string.split(),
                        ['python', 'is', 'a', 'best', 'language'])
        # check that test_string.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            test_string.split(2)

if __name__ == '__main__':
    unittest.main(verbosity=2)

Từ màn hình terminal, thực hiện chạy file trên, chúng ta thu được kết quả:

> python .\test_simple_unittest.pytest_islower (__main__.TestStringMethods) ... FAILtest_isupper (__main__.TestStringMethods) ... ok

# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
0
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
1
test_islower (__main__.TestStringMethods) ... FAIL
test_isupper (__main__.TestStringMethods) ... ok
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
0
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
1

# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
2
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
3
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
4
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
5
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
6
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
7
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
8
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
3
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
4
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
5
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
6
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
7
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
8

# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
4
# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
0
# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
0

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
1

Bây giờ chúng ta cùng nhau phân tích một chút về ví dụ trên.

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
2 --> Có nghĩa là module unittest là module đã được cài đặt cùng với gói cài đặt của Python.

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
3: --> module unittest cung cấp một class unittest.TestCase để các class khác thực hiện kế thừa.

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
4:, def test_isupper(self):, def test_split(self): --> các function đều bắt đầu bằng test_

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
5 --> Để khởi chạy các test case trong một module, cần đặt gọi đến unittest.main() của module đó. unittest.main() thường đặt ở cuối cùng của module (file code).

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
6 --> Các function dùng để so sánh và raise lên các message thông báo cho kết quả test chính chính xác hay không.

Trong trường kết quả test không chính xác, sẽ hiển thị ra bài test không pass được bằng cách trỏ đến dòng code và nguyên nhân gây ra lỗi.Như ví dụ trên, lỗi nằm ở dòng só 14 khi cố tình đặt

# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
7, và messagelỗi cũng chỉ ra đúng dòng lỗi là dòng 14, và nôi dung lỗi cũng rõ ràng
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
8
Như ví dụ trên, lỗi nằm ở dòng só 14 khi cố tình đặt
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
7, và messagelỗi cũng chỉ ra đúng dòng lỗi là dòng 14, và nôi dung lỗi cũng rõ ràng
# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​
8

2. Một số function trong unit-test thường dùng.

2.1. Các function trong unit-test trả về True/False

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)
9--> Trả về True: Nếu giá trị value1 == value2--> Trả về False: nếu value1 != value2
--> Trả về True: Nếu giá trị value1 == value2
--> Trả về False: nếu value1 != value2

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
0--> Trả về True: Nếu giá trị value == True--> Trả về False: nếu value1 == False
--> Trả về True: Nếu giá trị value == True
--> Trả về False: nếu value1 == False

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
1--> Trả về True: Nếu giá trị value == False--> Trả về False: nếu value1 == True
--> Trả về True: Nếu giá trị value == False
--> Trả về False: nếu value1 == True


# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
2
# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
3
# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
3

Trả về True: Nếu trong các expressions phát sinh ra lỗi TypeException Trả về False: Nếu trong expressions không phát sinh ra lỗi
Trả về False: Nếu trong expressions không phát sinh ra lỗi

2.2. Các function khác
Method Checks that
assertNotEqual(a, b) a != b
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b)
assertAlmostEqual(a, b) round(a-b, 7) == 0
assertNotAlmostEqual(a, b) round(a-b, 7) != 0
assertGreater(a, b) a > b
assertGreaterEqual(a, b) a >= b
assertLess(a, b) a < b
assertLessEqual(a, b) a
assertRegex(s, r) r.search(s)
assertNotRegex(s, r) not r.search(s)
assertCountEqual(a, b) a and b have the same elements in the same number, regardless of their order

2.3. Các function so sánh các kiểu dữ liệu khác nhau.. Các function so sánh các kiểu dữ liệu khác nhau.

Method Used to compare
assertMultiLineEqual(a, b) strings
assertSequenceEqual(a, b) sequences
assertListEqual(a, b) lists
assertTupleEqual(a, b) tuples
assertSetEqual(a, b) sets or frozensets
assertDictEqual(a, b) dicts

3. Cách chạy unittest.

Ở ví dụ phía trên, ngoài cách gọi trực tiếp vào module/file để thực thi, chúng ta có thể gọi unittest từng đơn vị như sau: file để thực thi, chúng ta có thể gọi unittest từng đơn vị như sau: 

Test cả module::

>

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
4

======================================================================

FAIL: test_islower (test_simple_unittest.TestStringMethods)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower"E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14in test_islower

    self.assertTrue('PYTHON'.islower())self.assertTrue('PYTHON'.islower())

AssertionError: False is not trueFalse is not true

----------------------------------------------------------------------

Ran 4 tests in 0.001s4 tests in 0.001s

FAILED (failures=1)failures=1)

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
5

======================================================================

FAIL: test_islower (test_simple_unittest.TestStringMethods)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower"E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14in test_islower

    self.assertTrue('PYTHON'.islower())self.assertTrue('PYTHON'.islower())

AssertionError: False is not trueFalse is not true

----------------------------------------------------------------------

Ran 4 tests in 0.001s4 tests in 0.001s

FAILED (failures=1)failures=1)

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
6

----------------------------------------------------------------------

Ran 1 test in 0.000s1 test in 0.000s

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))
7

======================================================================

FAIL: test_islower (test_simple_unittest.TestStringMethods)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower"E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14in test_islower

    self.assertTrue('PYTHON'.islower())self.assertTrue('PYTHON'.islower())

AssertionError: False is not trueFalse is not true

----------------------------------------------------------------------

Ran 1 test in 0.000s1 test in 0.000s

FAILED (failures=1)failures=1)

  File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower. Một số ví dụ về unittest

Test từng class/function trong module: Viết chương trình tìm nghiệm của phương trình bậc 1: aX + b = 0

Test từng function trong module

OK

4. Một số ví dụ về unittest0 và b == 0 -> phương trình vô số nghiệm, trả về ALL

Nếu a == 0 và b != 0 -> Phương trình vô nghiệm, trả về NONE0 và b != 0 -> Phương trình vô nghiệm, trả về NONE

Kết quả: X = -b / a 

Sau khi giải bài toàn và lưu vào file first_equation.pyfile first_equation.py

# first_equation.py
def find_x(a,b):
    if a:
        return -b/a
    elif b:
        return "NONE"
    else:
        return "ALL"

def find_x_2(a,b):
    return -b/a


if __name__ == "__main__":
    print(find_x(10,10))​

Thực hiện viết unittest của function trên.

# test_first_equation.py

import unittest
import first_equation

class TestFirst(unittest.TestCase):

    def test_find_x(self):
        args = (10, 10)
        self.assertEqual(first_equation.find_x(*args), -1)
        args = (0, 0)
        self.assertEqual(first_equation.find_x(*args), "ALL")
        args = (0, 10)
        self.assertEqual(first_equation.find_x(*args), "NONE")

if __name__ == '__main__':
    unittest.main(verbosity=2)

Thực hiện chạy thử, ta thu được kết quả:> python -m unittest test_first_equation.TestFirst.----------------------------------------------------------------------Ran 1 test in 0.000s
> python -m unittest test_first_equation.TestFirst
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Ví dụ 2: Cho 1 chuỗi cho trước, thực hiện tách chuỗi theo các khoảng trắng và trả về một list của các tuple dạng [(số thứ tự, giá trị),…]: Cho 1 chuỗi cho trước, thực hiện tách chuỗi theo các khoảng trắng và trả về một list của các tuple dạng [(số thứ tự, giá trị),…]

Input: test_str = "Python is a best language”
test_str = "Python is a best language”

Output:

[(1, 'Python'), (2, 'is'), (3, 'a'), (4, 'best'), (5, 'language')]


Code bài toán:

# list_value.py
data = "Python is a best language"

def create_value(data_str):
    input_data = data_str.split()
    result = []
    for index, element in enumerate(input_data):
        result.append((index + 1, element))
    return result

if __name__ == "__main__":
    print(create_value(data))

Viết unit-test cho bài toán:

# test_list_value.py
import unittest
import list_value

class TestStringMethods(unittest.TestCase):

    def test_create_tuple(self):
        test_str = list_value.data
        data_list = test_str.split()
        len_expected = len(data_list)
        result_list = list_value.create_value(test_str)
        self.assertIsInstance(result_list, list, "Dữ liệu trả về không đúng dạng list")
        for item in result_list:
            self.assertIsInstance(item, tuple, "Dữ liệu trả về không đúng dạng tuple")
        self.assertEqual(len(result_list), len_expected, "Số lượng phần tử không đúng")
        self.assertEqual(result_list[0][0], 1, 'Index phần tử đầu tiên không đúng')
        self.assertEqual(
            result_list[-1][0],
            len_expected,
            'Index phần tử cuối cùng không đúng'
        )


if __name__ == '__main__':
    unittest.main(verbosity=2)

Kết quả thực hiện: >python -m unittest test_list_value.py.----------------------------------------------------------------------Ran 1 test in 0.000s
>python -m unittest test_list_value.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Ví dụ 2: Cho 1 chuỗi cho trước, thực hiện tách chuỗi theo các khoảng trắng và trả về một list của các tuple dạng [(số thứ tự, giá trị),…] Xử lý chuỗi palindrome
Chuỗi palindrome có dạng: Chuỗi lớn hơn 1, Không phân biệt chữ hoa, thường, viết xuôi hay ngược đều thu được kết quả như nhau.
Hãy viết chương trình kiểm tra một chuỗi có phải là chuỗi palindrome không ?

Input: test_str = "Python is a best language”

[(1, 'Python'), (2, 'is'), (3, 'a'), (4, 'best'), (5, 'language')]
Output: True

Code bài toán:
Output: True


Viết unit-test cho bài toán:
Output: False

Kết quả thực hiện: >python -m unittest test_list_value.py.----------------------------------------------------------------------Ran 1 test in 0.000s

# palindrome.py

def check_palindrome(text):
    if len(text) <= 1:
        return False
    text = text.strip().lower().replace(' ', '')
    return text == text[::-1]


if __name__ == "__main__":
    text = "Noon"
    print(check_palindrome(text))

Ví dụ 3: Xử lý chuỗi palindromeChuỗi palindrome có dạng: Chuỗi lớn hơn 1, Không phân biệt chữ hoa, thường, viết xuôi hay ngược đều thu được kết quả như nhau.Hãy viết chương trình kiểm tra một chuỗi có phải là chuỗi palindrome không ?

# test_palindrome.py
import unittest
import palindrome


class TestExercise(unittest.TestCase):
    MESSAGE_FMT = 'Kết quả mong muốn là `{0}`, nhận được `{1}`: `{2}`'

    def _test_all(self, func, cases):
        for input_, expect in cases:
            output = func(input_)
            msg = self.MESSAGE_FMT.format(expect, output, input_)
            self.assertEqual(output, expect, msg)


class TestPalindrome(TestExercise):

    def test_check_palindrome(self):
        cases = [('ana', True),
                 ('Civic', True),
                 ('Python', False),
                 ('', False),
                 ('P', False),
                 ('Able was I ere I saw Elba', True)]
        self._test_all(palindrome.check_palindrome, cases)


if __name__ == '__main__':
    unittest.main(verbosity=2)

Dữ liệu mẫu:

Input: test_str = ”Civic”Output: True
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Ví dụ 2: Cho 1 chuỗi cho trước, thực hiện tách chuỗi theo các khoảng trắng và trả về một list của các tuple dạng [(số thứ tự, giá trị),…]

Input: test_str = "Python is a best language”FAIL --> Đó là lý do tại sao chúng ta cần phải viết unitest. Kết quả fail có nghĩa là chúng ta sẽ phải xem lại phần code chương trình, có thể đã có chỗ nào đó đã bị thay đổi để đưa so với ban đầu khiến cho chương trình hoạt động không được chuẩn xác.

[(1, 'Python'), (2, 'is'), (3, 'a'), (4, 'best'), (5, 'language')]

Code bài toán:
Source code chương trình được lưu trên github tại link: https://github.com/quangvinh2986/python-unittest.
Cảm ơn các bạn đã theo dõi bài viết.

Viết unit-test cho bài toán: