如何创建一个模式来过滤掉python测试文件

时间:2016-05-10 15:45:59

标签: python regex

我有一个bash脚本来执行我的python测试,我想过滤所有包含NOT_DONE的测试用例

这就是我试过的

python3 -m unittest discover -s ${FOLDER} -p 'test_((?!NOT_DONE).)*_ALL.py'

输入示例:

test_word_NOT_DONE_more_words_alot_more_words_ALL.py< - 此测试不应执行

但是这个应该:

test_word_more_words_alot_more_words_ALL.py

1 个答案:

答案 0 :(得分:0)

路径解决方案

目录结构

unittesting/
    launcher.py
    tests/
        __init__.py
        test_finished.py
        test_NOT_DONE.py
        folder/
            __init__.py
            test_finished2.py
            test_NOT_DONE2.py

每个测试文件内部都是print(__file__),嵌套在TestCase方法下。因此,只有在导入模块并运行测试用例时,才会执行。

代码:

import importlib
import os
import sys
import unittest


HOME = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, 'tests')


def check_file(file):
    '''Check if file is test'''

    return all((
        'NOT_DONE' not in file,
        file.endswith('.py'),
        file != '__init__.py'
    ))


def find_paths(home=HOME):
    '''Find all paths'''

    os.chdir(HOME)
    for root, dirs, files in os.walk('tests'):
        for file in files:
            if check_file(file):
                if root != 'tests':
                    yield os.path.join(root[len('tests/'):], file)
                else:
                    yield file

def normalize(path):
    '''Normalize path to dotted name'''

    path = os.path.splitext(path)[0]
    unix = path.replace('/', '.')
    return unix.replace('\\', '.')


def tests(paths=None):
    '''Load and run tests'''

    if paths is None:
        paths = map(normalize, find_paths())
    modules = (importlib.import_module(i) for i in paths)

    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    for module in modules:
        tests = loader.loadTestsFromModule(module)
        suite.addTests(tests)

    runner = unittest.TextTestRunner()
    runner.run(suite)


if __name__ == '__main__':
    tests()

正如您所看到的,这很快就会变得非常困难,并且很难管理。有一种更简单的方法。然而,它运行。

$ python /home/alex/git/unittesting/launcher.py
tests/test_finished.pyc
.tests/folder/test_finished2.pyc
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

Pythonic Solution

在我的每个文件中都没有完成,我把变量放到了NOT_DONE = True,每个类都有一个装饰器skipif

目录结构

unittesting/
    launcher.py
    tests/
        __init__.py
        test1.py
        test2.py
        folder/
            __init__.py
            test3.py
            test4.py

在此示例中,test2test4NOT_DONE = True,而test1test3NOT_DONE = False

示例文件如下:

import unittest

NOT_DONE = False

# CASES
# -----


@unittest.skipIf(NOT_DONE, 'Reason')
class TestPrint(unittest.TestCase):

    def test_print(self):
        print(__file__)


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

现在,我只想做:

$ python -m unittest discover tests
tests/test1.py
tests/folder/test3.py
.
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK (skipped=2)

最佳方法

未完成的单元测试应该有unittest.skipIf(True, 'Unfinished')行,因此您不仅可以在模块级别获得控制权,还可以在类级甚至方法级别获得控制权。在下面的例子中,我有一个完成的单元测试和一个未完成的单元测试。运行该示例会跳过第一个unittest,但运行模块的其余部分。

import unittest

# CASES
# -----


@unittest.skipIf(True, 'Not Finished')
class TestPrint(unittest.TestCase):

    def test_print(self):
        print(__file__)


class TestPrinting(unittest.TestCase):

    def test_print(self):
        print(__file__)


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