Selenium - 在循环中使用Python HTMLTestRunner / TextTestRunner时的结果

时间:2013-11-12 09:21:37

标签: python selenium data-driven-tests

如果在任何时候都不清楚(或者说白话不是很正确),我很抱歉,但我会尽我所能!

第一次实际发布在论坛中;)...

非常感谢那些知情人士的帮助。

我正在使用Selenium和Python绑定来跨多个平台(OS)和浏览器对基于Web的应用程序进行自动测试。

作为其中的一部分,我使用HTMLTestRunner模块在每次测试运行结束时生成报告。我的问题在于此。

我目前读取的代码的结果是,对于相应列表中的每个平台/浏览器组合,HTMLTestRunner模块已初始化并执行单个测试用例...反过来生成报告并关闭。

这会导致生成的报告自行覆盖(或导致格式化问题),因为HTMLTestRunner旨在初始化,然后执行所有测试用例,然后使用所有测试结果创建单个报告。

如果我使用'unittest.TextTestRunner()'代替HTMLTestRunner,那么基本上只会发生同样的事情,只有结果显然会显示在shell中。跑了1个测试......好吧......跑了1个测试......好的......等等

我尝试使用'unittest.main(exit = False)行,它实际上似乎适用于shell中显示的结果,例如,所有测试都在提供任何报告之前运行。

遗憾的是,我还没有找到在HTMLTestRunner中使用此功能的方法。

(我怀疑有人会回来使用元类来动态生成测试,而不是像这样循环执行代码行。虽然我已经调查了这一点,但我发现自己完全失去了如何实现这和许多开发者类型告诉我,这是避开我们的事情(不想在这里开始辩论!)。)

无论如何,我正在使用的代码的简化示例如下:

global platform_list

platform_list = ['XP','VISTA','LINUX','WIN8','MAC']

global browser_list

browser_list = ['internet explorer','firefox','chrome','safari','opera']

class configuration(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Remote(command_executor= executor, desired_capabilities={'platform': platform, 'browserName': browser})
        self.driver.implicitly_wait(30)
        self.base_url = environment
        self.verificationErrors = []
        self.accept_next_alert = True

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException, e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

class test_case_A(configuration):
    def test_case_A(self):
        try:
            some code
        except:
            some code

class test_case_B(test_case_A):
    def test_case_B(self):
        self.test_case_A()
        try:
            some code
        except:
            some code

unit_test_suite = unittest.TestSuite()
unit_test_suite.addTest(test_case_A('test_case_A')), (test_case_B('test_case_B'))

results = file('results.html', 'wb')

runner = HTMLTestRunner.HTMLTestRunner(stream = results, title = 'Whatever', description = 'Whatever')

global platform
global browser

for platform in platform_list:
    for browser in browser_list:
        unittest.TextTestRunner().run(unit_test_suite)

我只是想说明,虽然上述代码的某些元素可能是无关紧要的,例如全局声明,但它们在实际中是必需的!

任何帮助将不胜感激!非常感谢......

1 个答案:

答案 0 :(得分:1)

我不确定这个答案是否会对您有所帮助,因为根据我的理解,它可能需要对您的代码进行大量重组。

为了运行我的回归套件,我有一个特定的模块来构建回归套件,然后运行HTMLtestrunner

因此,我的每个带有多个测试用例的测试模块都被导入,添加到TestSuite,然后启动套件本身。

这是一个简短的例子:

from unittest import TestLoader, TestSuite
import HTMLTestRunner
import datetime
from root.nested.tests.test_class_1 import TestClass1
from root.nested.tests.test_class_2 import TestClass2

class RegressionSuite():

if __name__ == "__main__":

    file_name = datetime.datetime.now().strftime("%Y_%m_%d_%H%M_report.html")

    output = open(file_name, "wb")

    loader = TestLoader()
    suite = TestSuite((
                       loader.loadTestsFromTestCase(TestClass1),
                       loader.loadTestsFromTestCase(TestClass2)
                      ))
    runner = HTMLTestRunner(stream = output, verbosity = 1, title="Regression Suite")
    runner.run(suite)

执行此模块时,生成的HTML结果文件会列出每个带有摘要的测试类,并且可以显示详细信息以显示每个测试用例的结果。