seleniumbase / SeleniumBase

📊 Python's all-in-one framework for web crawling, scraping, testing, and reporting. Supports pytest. UC Mode provides stealth. Includes many tools.
https://seleniumbase.io
MIT License
4.45k stars 908 forks source link

If the setUp function in the use case fails (throws an exception), then tearDown will not be executed directly #2850

Closed WaterLoran closed 3 weeks ago

WaterLoran commented 3 weeks ago

The corresponding test script is:

coding: utf-8

from seleniumbase import BaseCase

class TestCheckAndJumpOnOpenOrganizationCode001(BaseCase):

def setUp(self):
    super().setUp()
    print("66666666")
    assert False

def test_check_and_jump_on_open_organization_code_001(self):

    print("22222222222222222222222222222222222222222222222222222")
    pass

def tearDown(self):
    super().tearDown()
    # 切换角色到 autotest, 从而确保有最大的权限
    print("3333333333333333333333333333333333333333333333333333333")

########################## Actual process information: image

############################# My expectations: It is expected that when the script fails to execute in the setup, the tearDown function can also be executed, which should be consistent with the execution logic of pytest

mdmintz commented 3 weeks ago

That's unittest logic. (Not from SeleniumBase, which inherits unittest logic.)

If the setUp() method fails, nothing else runs:

from unittest import TestCase

class MyTestClass(TestCase):
    def setUp(self):
        super().setUp()
        print("SetUp")
        assert False

    def test_base(self):
        print("TheTest")

    def tearDown(self):
        print("TearDown")
        super().tearDown()

If you want to make sure things get run, wrap unreliable code in a try/except block:

from unittest import TestCase

class MyTestClass(TestCase):
    def setUp(self):
        super().setUp()
        print("SetUp")
        try:
            assert False
        except Exception:
            pass

    def test_base(self):
        print("TheTest")

    def tearDown(self):
        print("TearDown")
        super().tearDown()

The same holds true with SeleniumBase: examples/boilerplates/base_test_case.py

WaterLoran commented 2 weeks ago

Thank you very much. Originally, it was due to directly inheriting the Unittest engine, which is different from the execution logic of Pytest. Therefore, I have this question. Thank you very much