写好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

原文地址:https://www.cnblogs.com/liangnote/p/5980002.html