编写测试
unittest
模块提供了一个编写和运行单元测试的框架。单元测试是一种测试软件的单独单元或组件,以确保它们自身是正常的。unittest
模块受 Java JUnit 测试框架的启发,遵循 xUnit 测试风格。
通过继承 unittest.TestCase
类来创建测试用例。每个测试用例由一个或多个执行特定测试场景的测试方法组成。
在测试用例类中可以定义 setUp
和 tearDown
方法,二者分别在每个测试方法之前和之后运行。
断言用于在测试执行期间验证某些条件是否满足。常见的断言包括 assertEqual
、assertNotEqual
、assertTrue
、assertFalse
等。
tests/test_grep.py:
import os
import shutil
import tempfile
import unittest
from grepy.grep import grep, grep_count, grep_recursive
class TestGrepFunctions(unittest.TestCase):
def setUp(self):
# 测试前创建临时目录
self.test_dir = tempfile.mkdtemp()
def tearDown(self):
# 测试后删除临时目录
shutil.rmtree(self.test_dir)
def test_grep_single_file(self):
# 创建测试文件
test_file_path = os.path.join(self.test_dir, 'test_file.txt')
with open(test_file_path, 'w') as test_file:
test_file.write("apple\nbanana\norange\n")
# 测试 grep 函数处理单个文件
result = grep('apple', test_file_path)
self.assertEqual(result, {test_file_path: [(1, 'apple')]})
def test_grep_ignore_case(self):
# 创建测试文件
test_file_path = os.path.join(self.test_dir, 'test_file.txt')
with open(test_file_path, 'w') as test_file:
test_file.write("apple\nBanana\norange\n")
# 测试 grep 函数不区分大小写的处理逻辑
result = grep('banana', test_file_path, options=['i'])
self.assertEqual(result, {test_file_path: [(2, 'Banana')]})
def test_grep_recursive(self):
# 创建嵌套目录及其文件
subdir_path = os.path.join(self.test_dir, 'subdir')
os.makedirs(subdir_path, exist_ok=True)
file1_path = os.path.join(self.test_dir, 'test_file1.txt')
file2_path = os.path.join(subdir_path, 'test_file2.txt')
with open(file1_path, 'w') as file1, open(file2_path, 'w') as file2:
file1.write("apple\nbanana\norange\n")
file2.write("apple\nkiwi\nbanana\n")
# 测试 grep_recursive 函数
result = grep_recursive('kiwi', self.test_dir)
expected_result = {file1_path: [], file2_path: [(2, 'kiwi')]}
self.assertEqual(result, expected_result)
def test_grep_count(self):
# 创建测试文件
test_file1_path = os.path.join(self.test_dir, 'test_file1.txt')
test_file2_path = os.path.join(self.test_dir, 'test_file2.txt')
with open(test_file1_path, 'w') as file1, open(test_file2_path, 'w') as file2:
file1.write("apple\nbanana\norange\n")
file2.write("apple\nkiwi\nbanana\n")
# 测试 grep_count 函数
result = grep_recursive('apple', self.test_dir)
count = grep_count(result)
self.assertEqual(count, 2)
if __name__ == '__main__':
unittest.main()
运行测试用例:
python3 -m unittest tests/test_grep.py
或者,使用 discover
子命令:
cd tests
python3 -m unittest discover
unittest
模块支持测试发现,可自动发现并运行目录或模块下的所有的用例。
应该得到如下结果:
....
----------------------------------------------------------------------
Ran 4 tests in 0.005s
OK
如果遇到错误,你会看到具体的断言报错信息,如下所示:
...F
======================================================================
FAIL: test_grep_single_file (tests.test_grep.TestGrepFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/projects/lr_grepy/tests/test_grep.py", line 26, in test_grep_single_file
self.assertEqual(result, {test_file_path: [(1, 'a2pple')]})
AssertionError: {'/va[27 chars]wgzbhddyr40000gn/T/tmp1qd0uxar/test_file.txt': [(1, 'apple')]} != {'/va[27 chars]wgzbhddyr40000gn/T/tmp1qd0uxar/test_file.txt': [(1, 'a2pple')]}
{'/var/folders/wx/hdjympxj7h3_ntwgzbhddyr40000gn/T/tmp1qd0uxar/test_file.txt': [(1,
- 'apple')]}
+ 'a2pple')]}
? +
----------------------------------------------------------------------
Ran 4 tests in 0.006s
FAILED (failures=1)
然后,你可以根据错误信息修复代码实现中的问题。