写好unit test的建议和例子
最近翻了下写unit test 的文章,总结如下
What’s unit test?
“Unit testing is a software testing method by which individual units of source code.” – –Wikipedia
What’s integration test?
“Integration testing is the phase in software testing in which individual software modules are combined and tested as a group” – Wikipedia
Goal for unit test
- Defects obvious bugs
- Provide an example about how to call it
- Refactor
Effective way to find bugs
- Integration test
- Manual test
How to write good unit test?
Arrange -> Act -> Assert
# zoo.py class Zoo: def __init__(self, animals): self.animals = animals def sort_by_name(self): self.animals = sorted(self.animals) def get_animals(self): return self.animals # test_zoo.py import unittest class Zoo: def __init__(self, animals): self.animals = animals def sort_by_name(self): self.animals = sorted(self.animals) def get_animals(self): return self.animals class TestZoo(unittest.TestCase): def test_sort_by_name(self): # Arrange: Set up test data bj_zoo = Zoo(['panda', 'elephant', 'tiger']) # Act: Execute the unit under test bj_zoo.sort_by_name() # Assert: Verify and log the result self.assertEqual(bj_zoo.animals[0], 'elephant')
Tests verify facts about the application, not exact results
Separate requirements into individual clauses
import cipher import decrypt import unittest def encrypt(str): # Encryption followed by decryption should return the original: # the encrypted text is as long as the original: # no character is encrypted to itself: entrypted_str = cipher.encrypt(str) return entrypted_str class TestEncypt(unittest.TestCase): def test_encrypt_bad(self): actual_encryption = encrypt('hello') expected_encryuption = 'ASDFG' self.assertEqual(actual_encryption, expected_encryuption) def test_encrypt_good(self): original_str = 'hello' self.assertEqual(original_str, decrypt(encrypt(original_str))) self.assertEqual(len(original_str), len(encrypt(original_str))) for i in xrange(0, len(original_str)): self.assertNotEqual(original_str[i], encrypt(original_str))
Test exception handling
import unittest from exceptions import ValueError def raise_exception(): raise ValueError('error msg foo') class TestRaiseException(unittest.TestCase): def test_raise_exception(self): self.assertRaises(ValueError, raise_exception)
Don’t only test one input value or state
import unittest from ddt import ddt, data, unpack def larger_than_two(num): if num > 2: return True @ddt class FooTestCase(unittest.TestCase): @data(3, 4, 12, 23) def test_larger_than_two(self, value): self.assertTrue(larger_than_two(value)) @data((3, 2), (4, 3), (5, 3)) @unpack def test_tuples_extracted_into_arguments(self, first_value, second_value): self.assertTrue(first_value > second_value)
Mock out all external services and state
# rm.py import os def rm(filename): os.remove(filename) # test_rm.py from rm import rm import mock import unittest import os def rm(filename): os.remove(filename) class RmTestCase(unittest.TestCase): @mock.patch('foomodule.os') def test_rm(self, mock_os): rm("any path") mock_os.remove.assert_called_with("any path")
Avoid unnecessary preconditions
Name clearly and consistently
Example
test_divide_zero_raise_exception
When and where to add unit test?
- When you need a block of comment
- Parts likely to fail
- Parts keep getting questions
Reference
https://developer.salesforce.com/page/How_to_Write_Good_Unit_Tests
http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
http://www.ibm.com/developerworks/cn/linux/l-tdd/index.html
https://msdn.microsoft.com/en-us/library/jj159340.aspx
posted on 2016-10-20 10:54 sdet_liang 阅读(859) 评论(0) 编辑 收藏 举报