标签归档:nosetests

如何在python中使用鼻子测试/单元测试来断言输出?

问题:如何在python中使用鼻子测试/单元测试来断言输出?

我正在为下一个功能编写测试:

def foo():
    print 'hello world!'

因此,当我要测试此功能时,代码将如下所示:

import sys
from foomodule import foo
def test_foo():
    foo()
    output = sys.stdout.getline().strip() # because stdout is an StringIO instance
    assert output == 'hello world!'

但是,如果我使用-s参数运行鼻子测试,则测试将崩溃。如何使用unittest或鼻子模块捕获输出?

I’m writing tests for a function like next one:

def foo():
    print 'hello world!'

So when I want to test this function the code will be like this:

import sys
from foomodule import foo
def test_foo():
    foo()
    output = sys.stdout.getline().strip() # because stdout is an StringIO instance
    assert output == 'hello world!'

But if I run nosetests with -s parameter the test crashes. How can I catch the output with unittest or nose module?


回答 0

我使用此上下文管理器捕获输出。通过临时替换,它最终使用了与其他一些答案相同的技术sys.stdout。我更喜欢上下文管理器,因为它将所有簿记功能都包装到一个函数中,因此,我不必重新编写任何最终代码,也不必为此编写设置和拆卸功能。

import sys
from contextlib import contextmanager
from StringIO import StringIO

@contextmanager
def captured_output():
    new_out, new_err = StringIO(), StringIO()
    old_out, old_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = new_out, new_err
        yield sys.stdout, sys.stderr
    finally:
        sys.stdout, sys.stderr = old_out, old_err

像这样使用它:

with captured_output() as (out, err):
    foo()
# This can go inside or outside the `with` block
output = out.getvalue().strip()
self.assertEqual(output, 'hello world!')

此外,由于退出with块后将恢复原始输出状态,因此我们可以使用与第一个捕获块相同的功能来设置第二个捕获块,使用设置和拆卸功能是不可能的,并且在最终尝试写入时会变得很冗长手动阻止。当测试的目的是将两个函数的结果相互比较而不是与某个预先计算的值进行比较时,该功能就派上用场了。

I use this context manager to capture output. It ultimately uses the same technique as some of the other answers by temporarily replacing sys.stdout. I prefer the context manager because it wraps all the bookkeeping into a single function, so I don’t have to re-write any try-finally code, and I don’t have to write setup and teardown functions just for this.

import sys
from contextlib import contextmanager
from StringIO import StringIO

@contextmanager
def captured_output():
    new_out, new_err = StringIO(), StringIO()
    old_out, old_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = new_out, new_err
        yield sys.stdout, sys.stderr
    finally:
        sys.stdout, sys.stderr = old_out, old_err

Use it like this:

with captured_output() as (out, err):
    foo()
# This can go inside or outside the `with` block
output = out.getvalue().strip()
self.assertEqual(output, 'hello world!')

Furthermore, since the original output state is restored upon exiting the with block, we can set up a second capture block in the same function as the first one, which isn’t possible using setup and teardown functions, and gets wordy when writing try-finally blocks manually. That ability came in handy when the goal of a test was to compare the results of two functions relative to each other rather than to some precomputed value.


回答 1

如果确实要执行此操作,则可以在测试期间重新分配sys.stdout。

def test_foo():
    import sys
    from foomodule import foo
    from StringIO import StringIO

    saved_stdout = sys.stdout
    try:
        out = StringIO()
        sys.stdout = out
        foo()
        output = out.getvalue().strip()
        assert output == 'hello world!'
    finally:
        sys.stdout = saved_stdout

但是,如果我正在编写此代码,则希望将可选out参数传递给该foo函数。

def foo(out=sys.stdout):
    out.write("hello, world!")

然后测试要简单得多:

def test_foo():
    from foomodule import foo
    from StringIO import StringIO

    out = StringIO()
    foo(out=out)
    output = out.getvalue().strip()
    assert output == 'hello world!'

If you really want to do this, you can reassign sys.stdout for the duration of the test.

def test_foo():
    import sys
    from foomodule import foo
    from StringIO import StringIO

    saved_stdout = sys.stdout
    try:
        out = StringIO()
        sys.stdout = out
        foo()
        output = out.getvalue().strip()
        assert output == 'hello world!'
    finally:
        sys.stdout = saved_stdout

If I were writing this code, however, I would prefer to pass an optional out parameter to the foo function.

def foo(out=sys.stdout):
    out.write("hello, world!")

Then the test is much simpler:

def test_foo():
    from foomodule import foo
    from StringIO import StringIO

    out = StringIO()
    foo(out=out)
    output = out.getvalue().strip()
    assert output == 'hello world!'

回答 2

从2.7版开始,您不再需要重新分配sys.stdout,这是通过bufferflag提供的。而且,这是鼻子测试的默认行为。

这是在非缓冲上下文中失败的示例:

import sys
import unittest

def foo():
    print 'hello world!'

class Case(unittest.TestCase):
    def test_foo(self):
        foo()
        if not hasattr(sys.stdout, "getvalue"):
            self.fail("need to run in buffered mode")
        output = sys.stdout.getvalue().strip() # because stdout is an StringIO instance
        self.assertEquals(output,'hello world!')

您可以设置缓冲区通过unit2命令行标志-b--bufferunittest.main选择。相反的是通过nosetestflag 实现的--nocapture

if __name__=="__main__":   
    assert not hasattr(sys.stdout, "getvalue")
    unittest.main(module=__name__, buffer=True, exit=False)
    #.
    #----------------------------------------------------------------------
    #Ran 1 test in 0.000s
    #
    #OK
    assert not hasattr(sys.stdout, "getvalue")

    unittest.main(module=__name__, buffer=False)
    #hello world!
    #F
    #======================================================================
    #FAIL: test_foo (__main__.Case)
    #----------------------------------------------------------------------
    #Traceback (most recent call last):
    #  File "test_stdout.py", line 15, in test_foo
    #    self.fail("need to run in buffered mode")
    #AssertionError: need to run in buffered mode
    #
    #----------------------------------------------------------------------
    #Ran 1 test in 0.002s
    #
    #FAILED (failures=1)

Since version 2.7, you do not need anymore to reassign sys.stdout, this is provided through buffer flag. Moreover, it is the default behavior of nosetest.

Here is a sample failing in non buffered context:

import sys
import unittest

def foo():
    print 'hello world!'

class Case(unittest.TestCase):
    def test_foo(self):
        foo()
        if not hasattr(sys.stdout, "getvalue"):
            self.fail("need to run in buffered mode")
        output = sys.stdout.getvalue().strip() # because stdout is an StringIO instance
        self.assertEquals(output,'hello world!')

You can set buffer through unit2 command line flag -b, --buffer or in unittest.main options. The opposite is achieved through nosetest flag --nocapture.

if __name__=="__main__":   
    assert not hasattr(sys.stdout, "getvalue")
    unittest.main(module=__name__, buffer=True, exit=False)
    #.
    #----------------------------------------------------------------------
    #Ran 1 test in 0.000s
    #
    #OK
    assert not hasattr(sys.stdout, "getvalue")

    unittest.main(module=__name__, buffer=False)
    #hello world!
    #F
    #======================================================================
    #FAIL: test_foo (__main__.Case)
    #----------------------------------------------------------------------
    #Traceback (most recent call last):
    #  File "test_stdout.py", line 15, in test_foo
    #    self.fail("need to run in buffered mode")
    #AssertionError: need to run in buffered mode
    #
    #----------------------------------------------------------------------
    #Ran 1 test in 0.002s
    #
    #FAILED (failures=1)

回答 3

对于我来说,这些答案很多都失败了,因为您无法from StringIO import StringIO使用Python3。这是基于@naxa的注释和Python Cookbook的最小工作片段。

from io import StringIO
from unittest.mock import patch

with patch('sys.stdout', new=StringIO()) as fakeOutput:
    print('hello world')
    self.assertEqual(fakeOutput.getvalue().strip(), 'hello world')

A lot of these answers failed for me because you can’t from StringIO import StringIO in Python 3. Here’s a minimum working snippet based on @naxa’s comment and the Python Cookbook.

from io import StringIO
from unittest.mock import patch

with patch('sys.stdout', new=StringIO()) as fakeOutput:
    print('hello world')
    self.assertEqual(fakeOutput.getvalue().strip(), 'hello world')

回答 4

在python 3.5中,您可以使用contextlib.redirect_stdout()StringIO()。这是对代码的修改

import contextlib
from io import StringIO
from foomodule import foo

def test_foo():
    temp_stdout = StringIO()
    with contextlib.redirect_stdout(temp_stdout):
        foo()
    output = temp_stdout.getvalue().strip()
    assert output == 'hello world!'

In python 3.5 you can use contextlib.redirect_stdout() and StringIO(). Here’s the modification to your code

import contextlib
from io import StringIO
from foomodule import foo

def test_foo():
    temp_stdout = StringIO()
    with contextlib.redirect_stdout(temp_stdout):
        foo()
    output = temp_stdout.getvalue().strip()
    assert output == 'hello world!'

回答 5

我只是在学习Python,并且发现自己遇到了与上述类似的问题,并且对带有输出的方法进行了单元测试。我上面对foo模块的传递单元测试最终看起来像这样:

import sys
import unittest
from foo import foo
from StringIO import StringIO

class FooTest (unittest.TestCase):
    def setUp(self):
        self.held, sys.stdout = sys.stdout, StringIO()

    def test_foo(self):
        foo()
        self.assertEqual(sys.stdout.getvalue(),'hello world!\n')

I’m only just learning Python and found myself struggling with a similar problem to the one above with unit tests for methods with output. My passing unit test for foo module above has ended up looking like this:

import sys
import unittest
from foo import foo
from StringIO import StringIO

class FooTest (unittest.TestCase):
    def setUp(self):
        self.held, sys.stdout = sys.stdout, StringIO()

    def test_foo(self):
        foo()
        self.assertEqual(sys.stdout.getvalue(),'hello world!\n')

回答 6

编写测试通常会向我们展示一种更好的编写代码的方法。与Shane的答案类似,我想提出另一种看待这个问题的方式。您是否真的要断言您的程序输出了某个字符串,还是只是构造了一个用于输出的字符串?这变得更容易测试,因为我们可能可以假设Python print语句正确完成了工作。

def foo_msg():
    return 'hello world'

def foo():
    print foo_msg()

然后您的测试非常简单:

def test_foo_msg():
    assert 'hello world' == foo_msg()

当然,如果您确实需要测试程序的实际输出,则可以忽略。:)

Writing tests often shows us a better way to write our code. Similar to Shane’s answer, I’d like to suggest yet another way of looking at this. Do you really want to assert that your program outputted a certain string, or just that it constructed a certain string for output? This becomes easier to test, since we can probably assume that the Python print statement does its job correctly.

def foo_msg():
    return 'hello world'

def foo():
    print foo_msg()

Then your test is very simple:

def test_foo_msg():
    assert 'hello world' == foo_msg()

Of course, if you really have a need to test your program’s actual output, then feel free to disregard. :)


回答 7

基于Rob Kennedy的回答,我编写了一个基于类的上下文管理器版本来缓冲输出。

用法就像:

with OutputBuffer() as bf:
    print('hello world')
assert bf.out == 'hello world\n'

这是实现:

from io import StringIO
import sys


class OutputBuffer(object):

    def __init__(self):
        self.stdout = StringIO()
        self.stderr = StringIO()

    def __enter__(self):
        self.original_stdout, self.original_stderr = sys.stdout, sys.stderr
        sys.stdout, sys.stderr = self.stdout, self.stderr
        return self

    def __exit__(self, exception_type, exception, traceback):
        sys.stdout, sys.stderr = self.original_stdout, self.original_stderr

    @property
    def out(self):
        return self.stdout.getvalue()

    @property
    def err(self):
        return self.stderr.getvalue()

Based on Rob Kennedy’s answer, I wrote a class-based version of the context manager to buffer the output.

Usage is like:

with OutputBuffer() as bf:
    print('hello world')
assert bf.out == 'hello world\n'

Here’s the implementation:

from io import StringIO
import sys


class OutputBuffer(object):

    def __init__(self):
        self.stdout = StringIO()
        self.stderr = StringIO()

    def __enter__(self):
        self.original_stdout, self.original_stderr = sys.stdout, sys.stderr
        sys.stdout, sys.stderr = self.stdout, self.stderr
        return self

    def __exit__(self, exception_type, exception, traceback):
        sys.stdout, sys.stderr = self.original_stdout, self.original_stderr

    @property
    def out(self):
        return self.stdout.getvalue()

    @property
    def err(self):
        return self.stderr.getvalue()

回答 8

或考虑使用pytest,它具有内置的断言stdout和stderr支持。查看文件

def test_myoutput(capsys): # or use "capfd" for fd-level
    print("hello")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    print("next")
    captured = capsys.readouterr()
    assert captured.out == "next\n"

Or consider using pytest, it has built-in support for asserting stdout and stderr. See docs

def test_myoutput(capsys): # or use "capfd" for fd-level
    print("hello")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    print("next")
    captured = capsys.readouterr()
    assert captured.out == "next\n"

回答 9

无论n611x007本体使用已经建议unittest.mock,但这个答案适应阿卡门斯的向您展示如何轻松地包裹unittest.TestCase方法与嘲笑互动stdout

import io
import unittest
import unittest.mock

msg = "Hello World!"


# function we will be testing
def foo():
    print(msg, end="")


# create a decorator which wraps a TestCase method and pass it a mocked
# stdout object
mock_stdout = unittest.mock.patch('sys.stdout', new_callable=io.StringIO)


class MyTests(unittest.TestCase):

    @mock_stdout
    def test_foo(self, stdout):
        # run the function whose output we want to test
        foo()
        # get its output from the mocked stdout
        actual = stdout.getvalue()
        expected = msg
        self.assertEqual(actual, expected)

Both n611x007 and Noumenon already suggested using unittest.mock, but this answer adapts Acumenus’s to show how you can easily wrap unittest.TestCase methods to interact with a mocked stdout.

import io
import unittest
import unittest.mock

msg = "Hello World!"


# function we will be testing
def foo():
    print(msg, end="")


# create a decorator which wraps a TestCase method and pass it a mocked
# stdout object
mock_stdout = unittest.mock.patch('sys.stdout', new_callable=io.StringIO)


class MyTests(unittest.TestCase):

    @mock_stdout
    def test_foo(self, stdout):
        # run the function whose output we want to test
        foo()
        # get its output from the mocked stdout
        actual = stdout.getvalue()
        expected = msg
        self.assertEqual(actual, expected)

回答 10

基于此线程中所有出色的答案,这就是我解决的方法。我想尽可能地保留它。我使用增强的单元测试机制setUp(),以捕获sys.stdoutsys.stderr,增加了新的API断言检查捕获的值对一个预期值,然后还原sys.stdoutsys.stderrtearDown(). I did this to keep a similar unit test API as the built-in单元测试API while still being able to unit test values printed tosys.stdout的orsys.stderr`。

import io
import sys
import unittest


class TestStdout(unittest.TestCase):

    # before each test, capture the sys.stdout and sys.stderr
    def setUp(self):
        self.test_out = io.StringIO()
        self.test_err = io.StringIO()
        self.original_output = sys.stdout
        self.original_err = sys.stderr
        sys.stdout = self.test_out
        sys.stderr = self.test_err

    # restore sys.stdout and sys.stderr after each test
    def tearDown(self):
        sys.stdout = self.original_output
        sys.stderr = self.original_err

    # assert that sys.stdout would be equal to expected value
    def assertStdoutEquals(self, value):
        self.assertEqual(self.test_out.getvalue().strip(), value)

    # assert that sys.stdout would not be equal to expected value
    def assertStdoutNotEquals(self, value):
        self.assertNotEqual(self.test_out.getvalue().strip(), value)

    # assert that sys.stderr would be equal to expected value
    def assertStderrEquals(self, value):
        self.assertEqual(self.test_err.getvalue().strip(), value)

    # assert that sys.stderr would not be equal to expected value
    def assertStderrNotEquals(self, value):
        self.assertNotEqual(self.test_err.getvalue().strip(), value)

    # example of unit test that can capture the printed output
    def test_print_good(self):
        print("------")

        # use assertStdoutEquals(value) to test if your
        # printed value matches your expected `value`
        self.assertStdoutEquals("------")

    # fails the test, expected different from actual!
    def test_print_bad(self):
        print("@=@=")
        self.assertStdoutEquals("@-@-")


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

运行单元测试时,输出为:

$ python3 -m unittest -v tests/print_test.py
test_print_bad (tests.print_test.TestStdout) ... FAIL
test_print_good (tests.print_test.TestStdout) ... ok

======================================================================
FAIL: test_print_bad (tests.print_test.TestStdout)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tests/print_test.py", line 51, in test_print_bad
    self.assertStdoutEquals("@-@-")
  File "/tests/print_test.py", line 24, in assertStdoutEquals
    self.assertEqual(self.test_out.getvalue().strip(), value)
AssertionError: '@=@=' != '@-@-'
- @=@=
+ @-@-


----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

Building on all the awesome answers in this thread, this is how I solved it. I wanted to keep it as stock as possible. I augmented the unit test mechanism using setUp() to capture sys.stdout and sys.stderr, added new assert APIs to check the captured values against an expected value and then restore sys.stdout and sys.stderr upon tearDown(). I did this to keep a similar unit test API as the built-inunittestAPI while still being able to unit test values printed tosys.stdoutorsys.stderr`.

import io
import sys
import unittest


class TestStdout(unittest.TestCase):

    # before each test, capture the sys.stdout and sys.stderr
    def setUp(self):
        self.test_out = io.StringIO()
        self.test_err = io.StringIO()
        self.original_output = sys.stdout
        self.original_err = sys.stderr
        sys.stdout = self.test_out
        sys.stderr = self.test_err

    # restore sys.stdout and sys.stderr after each test
    def tearDown(self):
        sys.stdout = self.original_output
        sys.stderr = self.original_err

    # assert that sys.stdout would be equal to expected value
    def assertStdoutEquals(self, value):
        self.assertEqual(self.test_out.getvalue().strip(), value)

    # assert that sys.stdout would not be equal to expected value
    def assertStdoutNotEquals(self, value):
        self.assertNotEqual(self.test_out.getvalue().strip(), value)

    # assert that sys.stderr would be equal to expected value
    def assertStderrEquals(self, value):
        self.assertEqual(self.test_err.getvalue().strip(), value)

    # assert that sys.stderr would not be equal to expected value
    def assertStderrNotEquals(self, value):
        self.assertNotEqual(self.test_err.getvalue().strip(), value)

    # example of unit test that can capture the printed output
    def test_print_good(self):
        print("------")

        # use assertStdoutEquals(value) to test if your
        # printed value matches your expected `value`
        self.assertStdoutEquals("------")

    # fails the test, expected different from actual!
    def test_print_bad(self):
        print("@=@=")
        self.assertStdoutEquals("@-@-")


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

When the unit test is run, the output is:

$ python3 -m unittest -v tests/print_test.py
test_print_bad (tests.print_test.TestStdout) ... FAIL
test_print_good (tests.print_test.TestStdout) ... ok

======================================================================
FAIL: test_print_bad (tests.print_test.TestStdout)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tests/print_test.py", line 51, in test_print_bad
    self.assertStdoutEquals("@-@-")
  File "/tests/print_test.py", line 24, in assertStdoutEquals
    self.assertEqual(self.test_out.getvalue().strip(), value)
AssertionError: '@=@=' != '@-@-'
- @=@=
+ @-@-


----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

如何在带有鼻息测试的文件中指定一个测试?

问题:如何在带有鼻息测试的文件中指定一个测试?

我有一个名为test_web.py的文件,其中包含一个TestWeb类和许多名为test_something()的方法。

我可以像这样运行类中的每个测试:

$ nosetests test_web.py 
...
======================================================================
FAIL: checkout test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/me/path/here/test_web.py", line 187, in test_checkout
...

但是我似乎无法运行单个测试。当在同一PWD中运行时,这些错误会给我“无此类测试”错误:

$ nosetests test_web.py:test_checkout
$ nosetests TestWeb:test_checkout

这有什么问题吗?

I have a file called test_web.py containing a class TestWeb and many methods named like test_something().

I can run every test in the class like so:

$ nosetests test_web.py 
...
======================================================================
FAIL: checkout test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/me/path/here/test_web.py", line 187, in test_checkout
...

But I can’t seem to run individual tests. These give me “No such test” errors when run in the same PWD:

$ nosetests test_web.py:test_checkout
$ nosetests TestWeb:test_checkout

What could be wrong here?


回答 0

您必须这样指定:nosetests <file>:<Test_Case>.<test_method>

nosetests test_web.py:TestWeb.test_checkout

查看文件

You must specify it like so: nosetests <file>:<Test_Case>.<test_method>, or

nosetests test_web.py:TestWeb.test_checkout

See the docs


回答 1

您还可以指定一个模块:

nosetests tests.test_integration:IntegrationTests.test_user_search_returns_users

You can also specify a module:

nosetests tests.test_integration:IntegrationTests.test_user_search_returns_users

回答 2

像其他答案所建议的那样,在命令行上指定名称确实有效并且很有用。但是,当我正在编写测试时,经常会发现我只想运行我正在进行的测试,并且我必须在命令行上编写的名称变得很长而且写起来很麻烦。在这种情况下,我更喜欢使用自定义装饰器和标志。

我这样定义wipd(“进行中的装饰器”):

from nose.plugins.attrib import attr
def wipd(f):
    return attr('wip')(f)

这定义了一个装饰器@wipd,该装饰器将wip在其装饰的对象上设置属性。例如:

import unittest
class Test(unittest.TestCase):

    @wipd
    def test_something(self):
        pass

然后-a wip可以在命令行中使用,以将测试的执行范围缩小到标有的测试@wipd

注意名称…

我使用@wipd装饰器的名称,而不是@wip避免这种问题:

import unittest
class Test(unittest.TestCase):

    from mymodule import wip    
    @wip
    def test_something(self):
        pass

    def test_something_else(self):
        pass

import将使wip装饰成员类的,以及所有在课堂测试将被选中。该attrib插件检查测试方法的父类,以查看所选属性是否也存在,并且创建和测试的属性attrib在隔离的空间中不存在。因此,如果您使用进行测试,-a foo并且您的类包含foo = "platypus",那么该插件中的所有测试都将被选中。

Specifying names on the command line like the other answers suggest does work and is useful. However, when I’m in the midst of writing tests, I often find that I want to run just the test I’m working on, and the names that I would have to write on the command line get pretty long and cumbersome to write. In such case, I prefer to use a custom decorator and flag.

I define wipd (“work in progress decorator”) like this:

from nose.plugins.attrib import attr
def wipd(f):
    return attr('wip')(f)

This defines a decorator @wipd which will set the wip attribute on objects it decorates. For instance:

import unittest
class Test(unittest.TestCase):

    @wipd
    def test_something(self):
        pass

Then -a wip can be used at the command line to narrow the execution of the test to the ones marked with @wipd.

Note on names…

I’m using the name @wipd for the decorator rather than @wip to avoid this kind of problem:

import unittest
class Test(unittest.TestCase):

    from mymodule import wip    
    @wip
    def test_something(self):
        pass

    def test_something_else(self):
        pass

The import will make the wip decorator a member of the class, and all tests in the class will be selected. The attrib plugin checks the parent class of a test method to see if the attribute selected exists there too, and the attributes that are created and tested by attrib do not exist in a segregated space. So if you test with -a foo and your class contains foo = "platypus", then all tests in the class will be selected by the plugin.


回答 3

要运行多个特定测试,您可以将它们添加到命令行中,并以空格分隔。

nosetests test_web.py:TestWeb.test_checkout test_web.py:TestWeb.test_another_checkout

To run multiple specific tests, you can just add them to the command line, separated by space.

nosetests test_web.py:TestWeb.test_checkout test_web.py:TestWeb.test_another_checkout

回答 4

在我的测试中,使用模块名称指定测试不起作用

您必须指定的实际路径.py

nosetests /path/to/test/file.py:test_function

这与 nose==1.3.7

In my tests, specifying tests with module names do not work

You must specify the actual path to the .py:

nosetests /path/to/test/file.py:test_function

This with nose==1.3.7


回答 5

我的要求是在另一个Windows目录中的测试文件中运行单个测试-这是通过anaconda命令提示符完成的,如下所示:

通过以下方式进行了鼻子测试

(base) C:\Users\ABC\Documents\work\

但是test_MyTestFile.pyMethodsFile.py位于:

 (base) C:\Users\ABC\Documents\work\daily\

通过包含引号的路径来运行单个测试,如下所示:

(base) C:\Users\ABC\Documents\work>nosetests "daily\\test_MyTestFile.py:MyTestClass.test_add_integers"

test_MyTestFile.py看起来像这样:

import methodsFile
import unittest

class MyTestClass(unittest.TestCase):

    def test_add_integers(self):
        assert methodsFile.add(5, 3) == 8

    def test_add_integers_zero(self):
        assert methodsFile.add(3, 0) == 3

MethodsFile.py看起来像这样:

def add(num1, num2):
        return num1 + num2

My requirement was to run a single test in a test file that was in another windows directory – this was done from the anaconda command prompt as follows:

ran nosetests from:

(base) C:\Users\ABC\Documents\work\

but test_MyTestFile.py and methodsFile.py were in:

 (base) C:\Users\ABC\Documents\work\daily\

run single test by including path with quotes as follows:

(base) C:\Users\ABC\Documents\work>nosetests "daily\\test_MyTestFile.py:MyTestClass.test_add_integers"

test_MyTestFile.py looked like this:

import methodsFile
import unittest

class MyTestClass(unittest.TestCase):

    def test_add_integers(self):
        assert methodsFile.add(5, 3) == 8

    def test_add_integers_zero(self):
        assert methodsFile.add(3, 0) == 3

methodsFile.py looked like this:

def add(num1, num2):
        return num1 + num2

鼻子测试正在捕获我的打印语句的输出。如何规避呢?

问题:鼻子测试正在捕获我的打印语句的输出。如何规避呢?

当我打字

$ nosetests -v mytest.py

通过所有测试后,我的所有打印输出均被捕获。我想查看打印输出,即使一切都通过了。

因此,我要做的是强制声明错误以查看输出,如下所示。

class MyTest(TestCase):

    def setUp(self):
        self.debug = False

    def test_0(self):
        a = .... # construct an instance of something
        # ... some tests statements
        print a.dump()
        if self.debug:
            eq_(0,1)

感觉很难受,必须有更好的方法。请赐教。

When I type

$ nosetests -v mytest.py

all my print outputs are captured when all tests pass. I want to see print outputs even everything passes.

So what I’m doing is to force an assertion error to see the output, like this.

class MyTest(TestCase):

    def setUp(self):
        self.debug = False

    def test_0(self):
        a = .... # construct an instance of something
        # ... some tests statements
        print a.dump()
        if self.debug:
            eq_(0,1)

It feels so hackish, there must be a better way. Enlighten me please.


回答 0

要么:

$ nosetests --nocapture mytest.py

要么:

$ NOSE_NOCAPTURE=1 nosetests mytests.py

(也可以在nose.cfg文件中指定,请参见nosetests --help

Either:

$ nosetests --nocapture mytest.py

Or:

$ NOSE_NOCAPTURE=1 nosetests mytests.py

(it can also be specified in the nose.cfg file, see nosetests --help)


回答 1

--nologcapture 

它对我有用

Use

--nologcapture 

it worked for me


回答 2

这是最近添加到鼻子的,而不是–nocapture做的:

鼻子测试

This was added recently to nose instead of –nocapture do this:

nosetests -s


回答 3

为了与http://travis-ci.org集成,我将其放入.travis.yml中

script:  "python setup.py nosetests -s"

其中setup.py包含:

setup(
    ...
    tests_require=['nose>=1.0'],
    test_suite='nose.collector',
)

In order to integrate with http://travis-ci.org I have put this into .travis.yml:

script:  "python setup.py nosetests -s"

where setup.py contains:

setup(
    ...
    tests_require=['nose>=1.0'],
    test_suite='nose.collector',
)