0
0
Selenium Pythontesting~15 mins

Conftest for shared fixtures in Selenium Python - Deep Dive

Choose your learning style9 modes available
Overview - Conftest for shared fixtures
What is it?
Conftest is a special Python file used in pytest to define fixtures that can be shared across multiple test files. Fixtures are reusable pieces of setup code that prepare the environment for tests, like opening a browser or setting test data. By placing fixtures in conftest.py, you avoid repeating the same setup in every test file. This makes tests cleaner and easier to maintain.
Why it matters
Without shared fixtures in conftest.py, you would have to copy the same setup code into every test file, which wastes time and causes errors if you forget to update one place. Shared fixtures help keep tests consistent and reduce bugs caused by setup mistakes. This saves time and effort when running many tests, especially in Selenium where browser setup is common.
Where it fits
Before learning conftest fixtures, you should understand basic pytest fixtures and how Selenium tests work. After mastering conftest, you can learn about pytest plugins, parameterized fixtures, and advanced test organization techniques.
Mental Model
Core Idea
Conftest.py acts like a shared toolbox where all your test setup tools (fixtures) live, so every test file can use them without copying.
Think of it like...
Imagine a kitchen where every cook needs the same set of knives and pots. Instead of each cook bringing their own, the kitchen has a shared drawer with all the tools ready to use. Conftest.py is that shared drawer for test setup.
conftest.py
  ├─ fixture: open_browser
  ├─ fixture: login_user
  └─ fixture: setup_test_data

Test file A.py ── uses open_browser, login_user
Test file B.py ── uses open_browser, setup_test_data

All fixtures come from conftest.py, no duplicates needed.
Build-Up - 7 Steps
1
FoundationUnderstanding pytest fixtures basics
🤔
Concept: Learn what fixtures are and how they help prepare test environments.
Fixtures are functions that run before your tests to set up things like browsers or data. You mark them with @pytest.fixture and then add them as arguments to your test functions. Pytest runs the fixture first and passes its result to the test.
Result
Tests can use setup code easily by just naming the fixture as a parameter.
Understanding fixtures is key because they let you write cleaner tests without repeating setup code.
2
FoundationCreating fixtures inside test files
🤔
Concept: How to write and use fixtures defined directly in a test file.
Inside a test file, define a fixture like this: import pytest @pytest.fixture def open_browser(): print('Opening browser') yield 'browser' print('Closing browser') def test_example(open_browser): assert open_browser == 'browser' Running this test shows the fixture runs before and after the test.
Result
The test runs with the browser fixture setup and teardown printed.
Knowing how to write fixtures locally helps you appreciate why sharing them is better for many tests.
3
IntermediateSharing fixtures with conftest.py
🤔Before reading on: do you think fixtures in conftest.py need to be imported in each test file? Commit to your answer.
Concept: Fixtures in conftest.py are automatically available to all tests in the same directory or subdirectories without imports.
Create a file named conftest.py in your test folder. Define fixtures there: import pytest @pytest.fixture def open_browser(): print('Opening browser') yield 'browser' print('Closing browser') Now in any test file in the same folder or below, you can use open_browser as a fixture without importing it.
Result
Tests can use open_browser fixture from conftest.py seamlessly.
Understanding automatic fixture discovery in conftest.py saves you from manual imports and keeps tests clean.
4
IntermediateScope and lifetime of shared fixtures
🤔Before reading on: do you think a fixture in conftest.py runs once per test or once per test session? Commit to your answer.
Concept: Fixtures can have different scopes like function, class, module, or session to control how often they run.
In conftest.py, you can set fixture scope: @pytest.fixture(scope='session') def open_browser(): print('Opening browser once') yield 'browser' print('Closing browser once') This fixture opens the browser once for all tests in the session, saving time.
Result
Fixture runs fewer times, speeding up tests and sharing resources.
Knowing fixture scopes helps optimize test speed and resource use in large test suites.
5
IntermediateUsing fixtures with parameters in conftest.py
🤔Before reading on: can conftest.py fixtures accept parameters to run tests with different data? Commit to your answer.
Concept: Fixtures in conftest.py can be parameterized to run tests multiple times with different inputs.
Example: @pytest.fixture(params=['chrome', 'firefox']) def browser(request): print(f'Opening {request.param}') yield request.param print(f'Closing {request.param}') Tests using browser fixture run twice, once per browser type.
Result
Tests run multiple times with different fixture parameters automatically.
Parameterizing shared fixtures enables broad test coverage with minimal code.
6
AdvancedOverriding fixtures in subdirectories
🤔Before reading on: do you think a fixture in a subfolder's conftest.py overrides the same fixture in a parent folder? Commit to your answer.
Concept: Fixtures defined in conftest.py files in subdirectories override fixtures with the same name from parent directories.
If you have conftest.py in root with open_browser fixture, and another conftest.py in a subfolder with a different open_browser fixture, tests in that subfolder use the local one. This allows customizing fixtures per folder.
Result
Tests use the closest fixture definition, enabling flexible setups.
Knowing fixture overriding helps organize tests with different needs in one project.
7
ExpertAvoiding common pitfalls with conftest fixtures
🤔Before reading on: do you think importing conftest.py directly in test files is recommended? Commit to your answer.
Concept: Directly importing conftest.py or fixtures can cause conflicts and is discouraged; rely on pytest's automatic discovery instead.
Conftest.py is discovered automatically by pytest based on folder structure. Importing it manually can cause duplicate fixture definitions or unexpected behavior. Instead, just use fixture names in tests and let pytest handle loading.
Result
Tests run smoothly without fixture conflicts or import errors.
Understanding pytest's discovery mechanism prevents subtle bugs and keeps test suites stable.
Under the Hood
Pytest searches for conftest.py files starting from the test file's directory up to the root. It loads fixtures from these files into a shared fixture namespace. When a test requests a fixture, pytest looks up the fixture by name in this namespace, preferring fixtures defined closest to the test file. Fixtures are functions that can yield resources and run teardown code after tests. Pytest manages fixture lifetimes based on scope, caching fixture results to avoid repeated setup.
Why designed this way?
Conftest.py was designed to avoid cluttering test files with setup code and to prevent explicit imports that can cause circular dependencies. This design allows modular, hierarchical fixture sharing and overrides, making large test suites easier to maintain. Alternatives like importing fixtures manually were rejected because they made test code verbose and fragile.
Test folder structure:

┌─────────────┐
│ conftest.py │  <-- defines shared fixtures
└─────┬───────┘
      │
      ├── test_login.py  <-- uses fixtures from conftest.py
      └── subfolder
          ├─ conftest.py  <-- can override fixtures
          └─ test_cart.py  <-- uses fixtures from subfolder conftest.py or parent

Fixture lookup:
Test file -> nearest conftest.py -> parent conftest.py -> ... -> pytest built-ins
Myth Busters - 4 Common Misconceptions
Quick: Do you think you must import fixtures from conftest.py in each test file? Commit to yes or no.
Common Belief:I must import fixtures from conftest.py explicitly in every test file to use them.
Tap to reveal reality
Reality:Pytest automatically discovers fixtures in conftest.py files based on folder structure; no imports are needed.
Why it matters:Manually importing fixtures can cause import errors, duplicate fixtures, or circular dependencies, breaking tests.
Quick: Do you think fixtures in conftest.py always run once per test session? Commit to yes or no.
Common Belief:All fixtures in conftest.py run once per test session by default.
Tap to reveal reality
Reality:Fixtures default to function scope, running before each test unless scope is explicitly set to module, class, or session.
Why it matters:Assuming session scope can cause tests to share state unexpectedly, leading to flaky or incorrect tests.
Quick: Can you override a fixture in a subfolder's conftest.py? Commit to yes or no.
Common Belief:Fixtures cannot be overridden; the first definition always applies.
Tap to reveal reality
Reality:Fixtures in subfolder conftest.py override fixtures with the same name in parent folders for tests in that subfolder.
Why it matters:Not knowing this can cause confusion when tests use unexpected fixture versions, making debugging harder.
Quick: Is it safe to import conftest.py directly in test files? Commit to yes or no.
Common Belief:Importing conftest.py directly in test files is a good way to share fixtures.
Tap to reveal reality
Reality:Direct imports can cause fixture duplication and conflicts; pytest's discovery should be used instead.
Why it matters:Ignoring this leads to subtle bugs and test failures that are hard to diagnose.
Expert Zone
1
Fixtures in conftest.py can be combined with pytest hooks to customize test collection and execution dynamically.
2
Using autouse=True in conftest.py fixtures applies setup automatically without needing to declare them in tests, but can cause hidden dependencies.
3
Fixture caching respects scope but can cause stale state if mutable objects are shared unintentionally across tests.
When NOT to use
Conftest.py fixtures are not ideal for very large projects with unrelated test suites; in such cases, consider pytest plugins or separate fixture modules imported explicitly. Also, avoid using conftest.py for fixtures that require complex dependencies better managed by dependency injection frameworks.
Production Patterns
In professional Selenium test suites, conftest.py commonly holds browser setup/teardown fixtures, login helpers, and test data loaders. Teams use layered conftest.py files to customize fixtures per feature folder. Parameterized fixtures in conftest.py enable cross-browser testing with minimal code duplication.
Connections
Dependency Injection
Conftest fixtures provide dependencies to tests similarly to dependency injection patterns in software design.
Understanding conftest fixtures as a form of dependency injection clarifies how tests receive resources cleanly and flexibly.
Modular Programming
Conftest.py promotes modularity by separating setup code from test logic, similar to modular code design.
Recognizing this connection helps appreciate how test code organization improves maintainability and reuse.
Shared Resources in Project Management
Just like teams share tools and documents to avoid duplication, conftest.py shares fixtures to avoid repeated setup.
Seeing conftest.py as a shared resource hub helps understand its role in collaboration and efficiency.
Common Pitfalls
#1Defining fixtures in conftest.py but trying to import them in test files.
Wrong approach:from conftest import open_browser def test_example(open_browser): assert open_browser == 'browser'
Correct approach:def test_example(open_browser): assert open_browser == 'browser'
Root cause:Misunderstanding pytest's automatic fixture discovery leads to unnecessary and error-prone imports.
#2Using function-scoped fixtures for expensive setup like browser launch in large test suites.
Wrong approach:@pytest.fixture def open_browser(): print('Opening browser') yield 'browser' print('Closing browser')
Correct approach:@pytest.fixture(scope='session') def open_browser(): print('Opening browser once') yield 'browser' print('Closing browser once')
Root cause:Not setting fixture scope causes slow tests due to repeated expensive setup.
#3Overriding fixtures unintentionally by defining same fixture name in multiple conftest.py files without realizing scope.
Wrong approach:# conftest.py in root def open_browser(): ... # conftest.py in subfolder def open_browser(): ...
Correct approach:Use unique fixture names or document overrides clearly to avoid confusion.
Root cause:Lack of awareness about fixture overriding rules causes unexpected test behavior.
Key Takeaways
Conftest.py is a special file where you put shared fixtures to reuse setup code across many test files without imports.
Pytest automatically finds fixtures in conftest.py based on folder structure, making tests cleaner and easier to maintain.
Fixture scope controls how often setup runs; setting it properly can speed up tests and avoid shared state bugs.
Fixtures in subfolder conftest.py override parent fixtures, allowing flexible test setups per folder.
Avoid importing conftest.py manually; rely on pytest's discovery to prevent conflicts and errors.