介绍

测试是检查Coala中编写的组件是否真的像应有的那样工作的基本要素。即使当您认为“我真的检查了我的代码,不需要测试”时,您也错了!不编写测试时引入的bug通常是最可怕的,它们的特点是无法发现(或者只有在几十个小时的搜索之后才能发现)。尽可能多地进行测试!你写的测试越多,你就越能确信你做的每件事都是正确的。特别是如果其他人修改了您的组件,他们可以通过您的测试确保不会引入错误。在编写测试时,请记住以下几点:

  • 100%测试覆盖率

  • 零冗余

除非分支机构覆盖率达到100%,否则不接受修补程序。冗余测试是在浪费精力,因为您要一遍又一遍地测试同一段代码,这是不必要的。

实际上是在写一个测试

那么,如何在Coala中实现测试呢?首先,测试放入 coala-bears/tests (如果您想为熊编写测试)或 coala/tests (如果测试为coalib编写的组件)目录。它们也是用Python(版本3)编写的,并通过运行以下命令自动执行:

$ pytest

只有一个约束:测试文件的名称必须以 Test.py (例如 MyCustomTest.py ,但不是 MyCustomTestSuite.py

备注

如果 pytest 似乎会给出错误,请尝试运行 python3 -m pytest 相反。

通常,您不想运行所有可用的测试。要运行您的特定程序,请键入(在Coala根文件夹中):

$ pytest -k <your-test>

您甚至可以给出部分名称或查询(如“not MyCustomTest”)来不运行特定的测试。有关更多信息,请参阅 pytest -h

接下来是测试文件结构。每个测试脚本都以您的导入开始。根据Coala代码风格(和Pep8风格),我们首先进行系统导入(如 resubprocessing ),然后是第一方导入(如 coalib.result.Result

然后是包含测试的实际测试套件类。每个测试套件都由测试用例组成,测试套件通过调用每个测试用例来检查组件的整体功能。

测试套件类的基本声明如下:

class YourComponentTest(unittest.TestCase):
    # Your test cases.
    pass

您应该从 unittest.TestCase 才能访问 setUp()tearDown() 功能(在下一节中介绍: SETUP()和TEARDOWN() )和断言函数。

现在来看测试用例:要实现测试用例,只需声明一个不带参数的类成员函数,以 test_ 。很简单,不是吗?

class YourComponentTest(unittest.TestCase):
    # Tests somethin'.
    def test_case1(self):
        pass

    # Doesn't test, this is just a member function, since the function name
    # does not start with 'test_'.
    def not_testing(self):
        pass

但是,您如何实际测试您的组件是否正确呢?为此,您有断言。断言检查条件是否满足,并将结果传递给管理Coala中所有测试的整个test-Suite-Invoking-Instance。结果会得到处理,如果测试中出现问题,您会收到一条消息。

参见

unittest assert-methods

有关Python内置单元测试中的断言函数的文档。

因此,成功的示例测试将是:

# The sys import and setup is not needed here because this example doesn't
# use coala components.
import unittest


class YourComponentTest(unittest.TestCase):
    # Tests somethin'.
    def test_case1(self):
        # Does '1' equal '1'? Interestingly it does... mysterious...
        self.assertEqual(1, 1)
        # Hm yeah, True is True.
        self.assertTrue(True)

备注

Coala中的测试是根据它们的覆盖率进行评估的,这意味着在调用测试用例时将从您的组件执行多少语句。任何提交都需要100%的分支机构覆盖率,才能推送到MASTER-如果您需要帮助提高覆盖率,请在GITER上询问我们!

分支机构覆盖率可以在本地使用 pytest --cov 命令。

参见

模块 Executing Tests

覆盖范围内运行测试的文档

由于我们的覆盖率是针对几个Python版本跨构建进行测量的(我们需要在这里和那里使用特定于版本的分支),因此您不会在本地获得完整的覆盖率!只需发出拉取请求即可自动测量覆盖范围。

如果某些代码无法测试,则需要用 # pragma: no cover 。重要提示:提供代码无法测试的原因。代码覆盖率是在Linux上使用python3.5测量的。

# Reason why this function is untestable.
def untestable_func(): # pragma: no cover
    # Untestable code.
    pass

setUp() and tearDown()

通常,您会重用组件,或者需要为测试进行初始设置。为此,该函数 setUp() 存在。只需在您的测试套件中声明它,它就会在测试套件启动时自动调用一次:

class YourComponentTest(unittest.TestCase):
    def setUp(self):
        # Your initialization of constants, operating system API calls etc.
        pass

与此相对的是 tearDown() 功能。它在测试套件运行完所有测试用例时被调用。声明它是这样的 setUp() 之前:

class YourComponentTest(unittest.TestCase):
    def tearDown(self):
        # Deinitialization, release calls etc.
        pass

KickStart

本节包含一个总结而简单的示例,您可以将其用作测试编写的起点。

将代码放在里面所需的文件夹下 tests 修改它,让它测试您的内容,然后使用以下命令从Coala根文件夹运行测试 pytest .

# Import here your needed system components.
import sys
import unittest

# Import here your needed coala components.


# Your test unit. The name of this class is displayed in the test
# evaluation.
class YourTest(unittest.TestCase):
    def setUp(self):
        # Here you can set up your stuff. For example constant values,
        # initializations etc.
        pass

    def tearDown(self):
        # Here you clean up your stuff initialized in setUp(). For example
        # deleting arrays, call operating system API etc.
        pass

    def test_case1(self):
        # A test method. Put your test code here.
        pass