关于在文件中存储控制台输出:将控制台输出存储在文件中 – Python,unittest

Store console output in a file - Python , unittest

我有一个python脚本,其中编写了一些单元测试,并且使用了Selenium。

我想提取控制台的整个输出(不仅是我的打印结果,还有与单元测试相关的结果),以便稍后在我的测试管理工具中导入它们。

Output

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import unittest
from selenium import webdriver
import json
import requests
import sys


class TestUbuntuHomepage(unittest.TestCase):
    global strs

    strs = []

    def setUp(self):
        sys.stdout = open("C:\\Users\\Marialena\\Downloads\\out2.log", 'wt')

        self.driver = webdriver.Firefox(executable_path="C:\\Users\\Marialena\\Downloads\\selenium-drivers\\geckodriver")


    def testTitle(self):
        self.driver.get('http://www.ubuntu.com/')

        if self.assertIn('Ubuntu', self.driver.title):
            strs.append('test'})


    def tearDown(self):
        self.driver.quit()


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

使用sys.stdout = open("C:\\Users\\Marialena\\Downloads\\out2.log", 'wt'),我将所有已打印的内容都保存在文件中,并且也会得到以下例外:

Traceback (most recent call last): File"C:\Program
Files\JetBrains\PyCharm\PyCharm Community Edition
2017.3.3\helpers\pycharm_jb_unittest_runner.py", line 35, in
main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner, buffer=not
JB_DISABLE_BUFFERING) File
"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\main.py",
line 95, in init
self.runTests() File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\main.py",
line 256, in runTests
self.result = testRunner.run(self.test) File"C:\Program Files\JetBrains\PyCharm\PyCharm Community Edition
2017.3.3\helpers\pycharm\teamcity\unittestpy.py", line 304, in run
return super(TeamcityTestRunner, self).run(test) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest
unner.py",
line 176, in run
test(result) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 84, in call
return self.run(*args, **kwds) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 122, in run
test(result) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 84, in call
return self.run(*args, **kwds) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 122, in run
test(result) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 84, in call
return self.run(*args, **kwds) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\suite.py",
line 122, in run
test(result) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\case.py",
line 653, in call
return self.run(*args, **kwds) File"C:\Users\Marialena\AppData\Local\Programs\Python\Python36-32\Lib\unittest\case.py",
line 624, in run
result.stopTest(self) File"C:\Program Files\JetBrains\PyCharm\PyCharm Community Edition
2017.3.3\helpers\pycharm\teamcity\unittestpy.py", line 260, in stopTest
output = sys.stdout.getvalue() AttributeError: '_io.TextIOWrapper' object has no attribute 'getvalue'

有什么帮助吗?谢谢您。


看起来pycharm正在用自己的流替换sys.stdout,所以当您用文件流替换它时,pycharm无法使用它。

因此,将你的干预限制在一个功能范围内,以避免干扰Pycharm。

这是一般的想法:

1
2
3
4
5
6
7
def testTitle(self):
    original_stdout = sys.stdout
    sys.stdout = open("C:\\Users\\Marialena\\Downloads\\out2.log", 'wt')

    # your test code goes here

    sys.stdout = original_stdout

现在,从外部看,它看起来像是sys.stdout从未被修改过。

当然,您需要改进以下方面:

  • finally块中处理测试-恢复stdout中的异常
  • 避免在每个测试中删除文件-以附加模式打开文件
  • 避免在每个测试中复制和粘贴此代码-创建上下文管理器
1
2
3
4
5
6
7
8
@contextmanager
def redirected_stdout(filename):
    original_stdout = sys.stdout
    sys.stdout = open(filename, 'at')
    try:
        yield
    finally:
        sys.stdout = original_stdout

然后:

1
2
3
def testTitle(self):
    with redirected_stdout("C:\\Users\\Marialena\\Downloads\\out2.log"):
        # your test code goes here

可选地:

调查pycharm期望sys.stdout如何工作,并创建自己的类,这两个类都可以:写入文件并提供pycharm期望的API。