Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›pytest & Testing›Quiz

pytest & Testing quiz

Ten questions at a time, drawn from 125. Every answer is explained. Nothing is saved and no account is needed.

Question 1 of 10Score 0

What is the primary reason for using a fixture instead of a standard setup function in pytest?

Practice quiz for pytest & Testing. Scores are not saved.

Study first?

Every question comes from a lesson in the pytest & Testing course.

Read the course →

Interview prep

Written questions with full answers.

pytest & Testing interview questions →

All pytest & Testing quiz questions and answers

  1. What is the primary reason for using a fixture instead of a standard setup function in pytest?

    • Fixtures are required to run tests in parallel.
    • Fixtures allow for modularity, dependency injection, and automatic teardown.
    • Fixtures are faster than standard Python functions.
    • Fixtures allow you to execute tests without using the assert keyword.

    Answer: Fixtures allow for modularity, dependency injection, and automatic teardown.. Fixtures enable dependency injection and systematic setup/teardown, which modularizes test environments. The other options are incorrect because fixtures are not strictly required for parallelism, they are not inherently faster, and they do not remove the need for assertions.

    From lesson: Introduction to Testing and pytest

  2. How does pytest determine which functions are tests?

    • By identifying functions decorated with @pytest.run.
    • By looking for functions that start with the 'test_' prefix.
    • By importing all functions that contain 'assert'.
    • By reading the naming convention defined in the conftest.py file.

    Answer: By looking for functions that start with the 'test_' prefix.. Pytest uses a default discovery pattern where it collects files starting with 'test_' and functions/methods within them starting with 'test_'. The other options refer to incorrect decorators, implementation details, or misinterpret the purpose of configuration files.

    From lesson: Introduction to Testing and pytest

  3. When a test function fails with an assertion error, what does pytest do?

    • It stops the entire test suite immediately.
    • It catches the error and marks the test as 'skipped'.
    • It uses internal introspection to provide a detailed report of the failure.
    • It prompts the user to manually enter a debug mode.

    Answer: It uses internal introspection to provide a detailed report of the failure.. Pytest performs assertion rewriting, allowing it to inspect the expression and show the values of the variables involved in the failure. It does not stop the suite by default, does not mark them as skipped, and does not require manual prompts.

    From lesson: Introduction to Testing and pytest

  4. What is the benefit of 'assert' rewriting in pytest?

    • It compiles the code into machine language for faster execution.
    • It allows developers to use plain 'assert' statements while getting rich failure diagnostics.
    • It enables the test suite to run on different operating systems.
    • It ensures that tests are only run if the environment is configured correctly.

    Answer: It allows developers to use plain 'assert' statements while getting rich failure diagnostics.. Assertion rewriting transforms the simple Python assert into a diagnostic powerhouse, reporting the state of the comparison at the moment of failure. It is not related to compilation, OS compatibility, or environment configuration.

    From lesson: Introduction to Testing and pytest

  5. Which of the following best describes the philosophy of an isolated test?

    • A test that executes without any dependencies on external systems or previous tests.
    • A test that only uses local variables defined within the test function.
    • A test that requires a dedicated database instance to verify functionality.
    • A test that runs in a separate process to prevent memory leaks.

    Answer: A test that executes without any dependencies on external systems or previous tests.. Isolation ensures that a test's outcome is independent of side effects from other tests or external state. Using local variables is just a coding style, requiring a database violates isolation, and separate processes are a performance optimization, not a definition of isolation.

    From lesson: Introduction to Testing and pytest

  6. Which of the following describes the purpose of the 'test_' prefix in pytest?

    • It is a required syntax for the Python interpreter
    • It acts as a marker for the test discovery process
    • It optimizes the execution speed of the test suite
    • It forces the test to run with elevated privileges

    Answer: It acts as a marker for the test discovery process. The 'test_' prefix is the default pattern pytest uses to discover files and functions; without it, pytest ignores the code. The other options are incorrect as it is a configuration convention, not a language requirement or performance optimization.

    From lesson: Writing Your First Test

  7. When a simple 'assert' statement fails in pytest, what is the primary benefit of the reporting system?

    • It automatically fixes the bug in the source code
    • It outputs a full memory dump of the testing process
    • It provides a detailed breakdown of the values involved in the expression
    • It sends an email notification to the developers

    Answer: It provides a detailed breakdown of the values involved in the expression. Pytest uses introspection to rewrite assertions, providing detailed info on variables during failure. It does not auto-fix code, dump memory, or handle notifications, as those are outside the scope of assertion reporting.

    From lesson: Writing Your First Test

  8. Why is it recommended to use fixtures over standard setup/teardown methods?

    • Fixtures allow tests to run in parallel without conflict
    • Fixtures provide modularity, dependency injection, and scope management
    • Fixtures are required by the Python language specification
    • Fixtures are the only way to import external libraries

    Answer: Fixtures provide modularity, dependency injection, and scope management. Fixtures offer scope management (e.g., session vs function) and dependency injection, making tests cleaner. Parallelism is handled by plugins, not fixtures themselves, and fixtures are not language requirements or needed for library imports.

    From lesson: Writing Your First Test

  9. What happens if a test function fails during its execution in a suite of 10 tests?

    • The entire test suite halts immediately
    • Pytest logs the error and continues to run the remaining tests
    • The failing test is automatically deleted to prevent future noise
    • The remaining tests are skipped to ensure data integrity

    Answer: Pytest logs the error and continues to run the remaining tests. Pytest is designed to run all discovered tests regardless of individual failures, reporting results at the end. It does not halt the suite, delete tests, or skip others unless explicitly configured to do so via command-line flags.

    From lesson: Writing Your First Test

  10. In the context of writing your first test, what does 'test isolation' imply?

    • Tests must be located in their own dedicated directory
    • A test should not rely on the state or side effects of another test
    • Tests must be run in complete network isolation
    • Every test needs to use a unique mock object

    Answer: A test should not rely on the state or side effects of another test. Isolation ensures that tests are independent, making them predictable and debuggable. The other options are either false requirements (directory structure) or specific implementation details (network or mocks) that do not define the core concept of isolation.

    From lesson: Writing Your First Test

  11. If your test output is missing print statements you included for debugging, what is the most direct way to see them in the console?

    • Use the --verbose flag
    • Use the -s flag
    • Use the -v flag
    • Use the --collect-only flag

    Answer: Use the -s flag. The -s flag allows output to be printed to stdout. --verbose and -v increase detail but do not disable capture, and --collect-only just lists tests without running them.

    From lesson: Running Tests and Reading Output

  12. Why does pytest not execute a function named 'check_login_functionality' even if it contains valid assertions?

    • It lacks a return statement
    • It needs to be inside a class
    • It does not start with the 'test_' prefix
    • It is not marked as a test

    Answer: It does not start with the 'test_' prefix. Pytest uses test discovery based on the prefix 'test_'. Changing the name to 'test_check_login_functionality' would allow pytest to find it automatically.

    From lesson: Running Tests and Reading Output

  13. What happens when an assertion fails midway through a test function?

    • The test is marked as skipped
    • The test is marked as errored
    • The execution stops immediately, and the remainder of the test is skipped
    • The test continues to the next assertion

    Answer: The execution stops immediately, and the remainder of the test is skipped. Pytest treats an assertion failure as a failure that terminates the execution of that specific test function immediately. It is not skipped or errored; it is failed.

    From lesson: Running Tests and Reading Output

  14. How can you run only a specific subset of tests defined by a keyword in their name?

    • Using the -k flag
    • Using the -m flag
    • Using the --collect-only flag
    • Using the -n flag

    Answer: Using the -k flag. The -k flag allows filtering tests by matching substrings in their names. -m is for markers, -n is for parallelization, and --collect-only is for inspection.

    From lesson: Running Tests and Reading Output

  15. Which of the following describes the best practice for reading test failure output?

    • Read only the first line of the output
    • Ignore the traceback and focus on the summary line
    • Look for the assertion failure details in the 'FAILURES' section of the output
    • Restart the suite with the --force-regen flag

    Answer: Look for the assertion failure details in the 'FAILURES' section of the output. The 'FAILURES' section provides the specific line where the assertion failed and the values of the variables involved, which is essential for debugging. The other options ignore critical diagnostic data.

    From lesson: Running Tests and Reading Output

  16. Which file naming pattern does pytest use by default for test discovery?

    • spec_*.py
    • test_*.py or *_test.py
    • tests_*.py
    • case_*.py

    Answer: test_*.py or *_test.py. pytest uses 'test_*.py' and '*_test.py' to identify test modules. Other options like 'spec_' or 'case_' are not standard pytest conventions and would require manual configuration.

    From lesson: Test Discovery and Naming Conventions

  17. If you have a function named 'calculate_sum' inside a test file, what will happen?

    • pytest will run it as a test automatically
    • pytest will error out during collection
    • pytest will ignore the function during execution
    • pytest will treat it as a fixture

    Answer: pytest will ignore the function during execution. pytest only discovers functions prefixed with 'test_'. Since 'calculate_sum' lacks this prefix, it is treated as a standard helper function and ignored by the test runner.

    From lesson: Test Discovery and Naming Conventions

  18. Why is it important to follow consistent naming conventions in a test suite?

    • It improves performance by reducing collection time
    • It allows pytest to discover and execute tests automatically
    • It is required by the Python language interpreter
    • It prevents naming collisions with production code

    Answer: It allows pytest to discover and execute tests automatically. Naming conventions allow pytest's discovery mechanism to locate tests without explicit configuration. Performance, language rules, and collision prevention are not the primary reasons for these specific naming patterns.

    From lesson: Test Discovery and Naming Conventions

  19. How does pytest handle test classes that do not start with 'Test'?

    • It runs them as regular test suites
    • It treats them as fixtures
    • It skips them by default during collection
    • It raises a warning but executes them anyway

    Answer: It skips them by default during collection. pytest skips classes that do not start with 'Test' by default, as they do not meet the collection criteria. It will not treat them as fixtures nor will it execute them.

    From lesson: Test Discovery and Naming Conventions

  20. When should you use a custom pytest configuration for discovery?

    • When you prefer using 'check_' as a prefix instead of 'test_'
    • When your project has thousands of tests
    • When you want to run tests in a specific folder
    • When you are using multiple testing frameworks

    Answer: When you prefer using 'check_' as a prefix instead of 'test_'. Custom configuration is specifically for changing the default discovery rules, such as supporting 'check_' prefixes. Project size, folder location, and multiple frameworks do not necessitate changing discovery patterns.

    From lesson: Test Discovery and Naming Conventions

  21. What is the primary benefit of using 'yield' in a fixture over 'return'?

    • It allows the fixture to be used in multiple test files
    • It provides a clear point to perform teardown code after the test finishes
    • It makes the fixture run faster by skipping variable initialization
    • It automatically resets the test database to its initial state

    Answer: It provides a clear point to perform teardown code after the test finishes. Yield allows code after the statement to run as teardown, which is essential for cleanup. Return simply passes the object, whereas yield pauses the fixture, runs the test, and resumes execution to finish the teardown. The other options are incorrect because they describe unrelated or false performance/scope benefits.

    From lesson: Fixtures — Setup and Teardown

  22. If you have a 'session' scoped fixture, when is its teardown code executed?

    • Immediately after each test function completes
    • After every class in the test suite
    • Only after all tests in the entire session have finished
    • Whenever the fixture is no longer needed by a specific module

    Answer: Only after all tests in the entire session have finished. Session scope means the fixture is created once for the entire test run and torn down only once, at the very end. Option 1 describes function scope; option 2 describes class scope; option 4 is not how pytest scoping works.

    From lesson: Fixtures — Setup and Teardown

  23. When should you define a fixture in 'conftest.py' instead of a local test file?

    • When the fixture performs a network request
    • When the fixture needs to be shared across multiple test files
    • When the fixture depends on a library that is not standard
    • When you want the fixture to run only once per test file

    Answer: When the fixture needs to be shared across multiple test files. conftest.py is automatically discovered by pytest and makes fixtures available to all tests in that directory and subdirectories. Defining it locally limits it to one file. The other options do not dictate location; scope dictates performance or frequency, not file placement.

    From lesson: Fixtures — Setup and Teardown

  24. What happens if a fixture used by a test fails during the setup phase?

    • The test is marked as 'failed' and teardown is skipped
    • The test is skipped automatically
    • The test is marked as 'error' and execution stops
    • The fixture is retried three times before failing

    Answer: The test is marked as 'error' and execution stops. A failure in setup occurs before the test starts, which pytest classifies as an 'error' rather than a test 'failure'. Options 1 and 2 are incorrect because the test suite does not just proceed or ignore the error; option 4 describes retry plugins, not default behavior.

    From lesson: Fixtures — Setup and Teardown

  25. How do you ensure a specific setup/teardown sequence if one fixture depends on another?

    • List the required fixture as an argument in the dependent fixture's definition
    • Use a global variable to track which fixture ran first
    • Name the fixtures in alphabetical order
    • Use the @pytest.mark.dependency decorator on the test function

    Answer: List the required fixture as an argument in the dependent fixture's definition. Pytest handles dependency injection by resolving arguments; if fixture B requests fixture A as an argument, pytest guarantees A is set up before B. Global variables are bad practice, and naming has no impact on execution. The dependency mark is for test-to-test dependency, not fixture management.

    From lesson: Fixtures — Setup and Teardown

  26. You have a suite where multiple test classes require a database connection. If you want the connection to be opened once per module to save time, which scope should you use?

    • function
    • class
    • module
    • session

    Answer: module. Module scope ensures the fixture runs once for the entire file (module), which is the intended goal. Function scope would be too slow, class scope wouldn't share across classes in the same module, and session scope is overkill and risks state leakage if only one module needs it.

    From lesson: Fixture Scopes — function, class, module, session

  27. What happens if a test function requires a 'function' scoped fixture that depends on a 'session' scoped fixture?

    • Pytest raises an error because scopes are incompatible.
    • The session fixture is re-initialized for every function.
    • The session fixture is initialized once and reused by the function fixture.
    • The function fixture will override the session fixture configuration.

    Answer: The session fixture is initialized once and reused by the function fixture.. Lower-scoped fixtures can depend on higher-scoped ones without issue. The session fixture remains alive for the duration of the test run, while the function fixture is created fresh for each test. Option 1 is false, Option 2 defeats the purpose of session, and Option 4 is syntactically impossible.

    From lesson: Fixture Scopes — function, class, module, session

  28. Why would you choose 'function' scope over 'session' scope for a fixture that clears a temporary directory?

    • To ensure each test starts with a completely empty directory.
    • Because 'session' scope cannot be used for file operations.
    • To allow tests to run in parallel more efficiently.
    • Because 'session' scope only works for class-based tests.

    Answer: To ensure each test starts with a completely empty directory.. Function scope ensures isolation; if one test leaves files in the directory, the next test won't see them because the fixture re-runs. Session scope would mean all tests share the same directory, leading to file collisions. The other options are factually incorrect regarding pytest capabilities.

    From lesson: Fixture Scopes — function, class, module, session

  29. If you have a base test class with a 'class' scoped fixture, and a subclass that inherits from it, how many times does the fixture run?

    • Once for the base class and once for each subclass.
    • Once for the entire class hierarchy.
    • Every time a method is called within either class.
    • It depends on the number of test methods in the base class.

    Answer: Once for the base class and once for each subclass.. Pytest scopes are applied to the specific class they are defined in. If the fixture is defined in the base class, subclasses will trigger the fixture again upon their own execution. Option 1 is the correct behavior; others misunderstand the scope's lifecycle.

    From lesson: Fixture Scopes — function, class, module, session

  30. Which of the following scenarios best justifies the use of a 'session' scoped fixture?

    • Initializing a complex UI component for a specific test function.
    • Setting up a local mock server that needs to be active for the entire test suite.
    • Creating a fresh user database entry for a single test case.
    • Preparing a local file to be read by tests in a single file.

    Answer: Setting up a local mock server that needs to be active for the entire test suite.. Session scope is ideal for expensive resources that are needed globally, such as a mock server. Function scope (Option 1 and 3) is better for specific test requirements, and module scope (Option 4) is better for single-file dependencies to avoid unnecessary global overhead.

    From lesson: Fixture Scopes — function, class, module, session

  31. How does pytest determine which tests have access to a fixture defined in a conftest.py file?

    • The fixture must be imported at the top of the test module.
    • The fixture is available to all tests in the same directory and all subdirectories.
    • The fixture is only available if it is decorated with @pytest.mark.global.
    • The fixture must be explicitly registered in a pytest.ini file.

    Answer: The fixture is available to all tests in the same directory and all subdirectories.. Pytest uses a directory-based scope for conftest.py files. It is available to the directory containing the file and all subdirectories. Importing is unnecessary and discouraged; global marks and ini registration are not required for fixture discovery.

    From lesson: conftest.py — Shared Fixtures

  32. If you have a conftest.py in the root folder and another in a subdirectory, which one takes precedence for a test in that subdirectory?

    • The root conftest.py takes precedence.
    • Both are merged, but the root one executes first.
    • The one in the subdirectory takes precedence.
    • Pytest will throw a collection error due to naming conflicts.

    Answer: The one in the subdirectory takes precedence.. Pytest follows a hierarchical lookup; the conftest.py closest to the test file takes precedence, allowing for overrides or local modifications. Merging is not the mechanism used for same-named fixtures; shadowing is.

    From lesson: conftest.py — Shared Fixtures

  33. What is the primary benefit of using a yield fixture in conftest.py compared to a return fixture?

    • It improves performance by reducing memory usage.
    • It allows for explicit teardown code to run after the test completes.
    • It forces the fixture to be executed before any other setup code.
    • It allows the fixture to be used as a class-level variable.

    Answer: It allows for explicit teardown code to run after the test completes.. Yield fixtures allow you to perform setup before 'yield' and cleanup after, which is essential for shared resources. Return fixtures have no built-in mechanism for teardown. Performance and scope are independent of the yield keyword.

    From lesson: conftest.py — Shared Fixtures

  34. When is an 'autouse' fixture defined in a conftest.py executed?

    • Only when it is requested by the test function arguments.
    • Every time pytest starts a new session.
    • For every test case within the scope of the conftest.py file.
    • Only when the test module is explicitly imported.

    Answer: For every test case within the scope of the conftest.py file.. An autouse fixture automatically runs for every test in its scope without needing to be named in the test function parameters. Session-wide is an option for scope, but it doesn't describe the triggering mechanism, and the other options are incorrect.

    From lesson: conftest.py — Shared Fixtures

  35. You have a fixture in conftest.py that is slow to initialize. You want it to run only once per test file rather than for every test function. How should you define the scope?

    • Use scope='session'.
    • Use scope='module'.
    • Use scope='function'.
    • Use scope='class'.

    Answer: Use scope='module'.. Setting scope='module' ensures the fixture setup runs once for each test file (module). 'Session' runs once per test run, 'function' runs for every test, and 'class' runs per test class, making module the correct choice for file-level reuse.

    From lesson: conftest.py — Shared Fixtures

  36. What is the primary advantage of using a factory pattern fixture over a static object fixture?

    • It speeds up execution by skipping the setup phase
    • It allows tests to customize the generated data on a per-test basis
    • It automatically detects and deletes unused database tables
    • It reduces the total number of lines of code in the project

    Answer: It allows tests to customize the generated data on a per-test basis. The factory pattern provides a callable fixture that allows tests to override specific fields, providing flexibility. Static fixtures don't do this (Option 2). Speed isn't the primary goal (Option 1). It doesn't handle database cleanup (Option 3). Code length is not the main benefit (Option 4).

    From lesson: Fixture Dependencies and Factories

  37. If two fixtures depend on each other, what happens when a test requests them?

    • Pytest raises an error about a circular dependency
    • Pytest runs both fixtures in parallel
    • Pytest executes them in the order they are defined in the file
    • Pytest ignores the dependency and initializes them randomly

    Answer: Pytest raises an error about a circular dependency. Pytest detects circular dependencies during the dependency resolution phase and raises a RecursionError. It does not run them in parallel (Option 2), order of definition is irrelevant (Option 3), and it does not ignore the dependency (Option 4).

    From lesson: Fixture Dependencies and Factories

  38. What is the purpose of the 'yield' keyword in a pytest fixture?

    • To return multiple values to the test
    • To pause the test execution until the database is ready
    • To separate the setup code from the teardown/cleanup code
    • To bypass the fixture scope restriction

    Answer: To separate the setup code from the teardown/cleanup code. Yield is the standard way to provide a teardown phase; code before yield runs before the test, and code after runs after the test. It does not return multiple values (Option 1), pause tests for the database (Option 2), or bypass scope (Option 4).

    From lesson: Fixture Dependencies and Factories

  39. Which scope should you choose for a fixture that creates a temporary database connection that must be fresh for every test?

    • session
    • module
    • class
    • function

    Answer: function. Function scope ensures the fixture is recreated for every individual test function, providing isolation. Session, module, and class scopes persist the fixture longer than a single test, which risks cross-test contamination.

    From lesson: Fixture Dependencies and Factories

  40. Why is it recommended to use 'autouse=True' sparingly?

    • Because it makes it difficult to track which fixtures affect a specific test
    • Because it causes tests to run significantly slower than normal
    • Because it breaks the fixture dependency injection mechanism entirely
    • Because it prevents fixtures from using the yield keyword

    Answer: Because it makes it difficult to track which fixtures affect a specific test. Autouse fixtures run implicitly, making it hard to see dependencies in the test signature. It doesn't inherently slow things down (Option 2), break DI (Option 3), or prevent yield (Option 4).

    From lesson: Fixture Dependencies and Factories

  41. What happens if you provide a list of tuples to @pytest.mark.parametrize where the tuple lengths do not match the number of argument names?

    • Pytest uses None for missing values
    • Pytest raises an error during collection
    • The test is skipped automatically
    • Only the first tuple is executed

    Answer: Pytest raises an error during collection. Pytest requires a strict mapping between the argument names string and the values in the tuples. If they don't align, the collection phase fails because it cannot map the inputs to the function arguments.

    From lesson: pytest.mark.parametrize — Multiple Inputs

  42. Which of the following correctly defines multiple inputs for a test function?

    • @pytest.mark.parametrize('x', 'y', [(1, 2), (3, 4)])
    • @pytest.mark.parametrize(['x', 'y'], [(1, 2), (3, 4)])
    • @pytest.mark.parametrize('x, y', [(1, 2), (3, 4)])
    • @pytest.mark.parametrize({'x', 'y'}, [(1, 2), (3, 4)])

    Answer: @pytest.mark.parametrize('x, y', [(1, 2), (3, 4)]). Pytest expects a single string of comma-separated names as the first argument, followed by a list of tuples for the values. Using lists, sets, or separate strings for names is incorrect syntax.

    From lesson: pytest.mark.parametrize — Multiple Inputs

  43. Why is it generally preferred to use @pytest.mark.parametrize over using a for-loop inside a test function?

    • It makes the test run significantly faster
    • It reduces the memory footprint of the test suite
    • Each parameter set is treated as an individual test result
    • It allows the test to run in parallel without configuration

    Answer: Each parameter set is treated as an individual test result. Using parametrize creates independent test nodes. If one case fails, the others continue running, and you get a clear report of which specific input caused the failure, whereas a loop stops at the first assertion error.

    From lesson: pytest.mark.parametrize — Multiple Inputs

  44. If you have a test function `def test_add(a, b, expected):`, how should the values be passed to correctly map the parameters?

    • [(1, 2, 3), (4, 5, 9)]
    • [[1, 2, 3], [4, 5, 9]]
    • [(1, 4), (2, 5), (3, 9)]
    • {(1, 2, 3), (4, 5, 9)}

    Answer: [(1, 2, 3), (4, 5, 9)]. Pytest expects an iterable of tuples, where each tuple corresponds to the full set of arguments for one test run. Lists of lists are sometimes accepted by duck typing but tuples are the convention, while sets are unordered and incorrect here.

    From lesson: pytest.mark.parametrize — Multiple Inputs

  45. What is the purpose of the 'ids' argument in @pytest.mark.parametrize?

    • To define the types of the input arguments
    • To provide custom names for each test case in the output
    • To verify that the inputs match the expected schema
    • To filter out specific test cases from the execution

    Answer: To provide custom names for each test case in the output. The 'ids' argument allows you to provide descriptive labels for each test case, making the test output much easier to read when debugging failures, as opposed to default index-based labels.

    From lesson: pytest.mark.parametrize — Multiple Inputs

  46. What is the primary advantage of using a custom mark over string-based filtering with the -k option?

    • It makes the test run significantly faster by skipping imports
    • It provides a semantic, stable identifier that survives code refactoring
    • It automatically generates a report file without needing extra plugins
    • It forces the test to run in a specific order relative to other tests

    Answer: It provides a semantic, stable identifier that survives code refactoring. Custom marks are semantic identifiers attached to test nodes, which remain stable even if test names change. String-based -k filtering is brittle because it depends on function names. Other options are incorrect as marks do not influence execution speed by skipping imports, report generation, or test order.

    From lesson: Custom Marks and Filtering Tests

  47. When running 'pytest -m slow', what happens if a test is marked with @pytest.mark.slow but is not registered in the configuration file?

    • pytest terminates with an immediate error
    • The test is skipped automatically by default
    • The test runs, but pytest issues a warning
    • The test is treated as a standard unit test

    Answer: The test runs, but pytest issues a warning. Pytest allows the use of unregistered marks but issues a 'PytestUnknownMarkWarning' to alert the developer of potential typos. It does not terminate, skip the test, or treat it as a standard unit test unless configured to fail on warnings.

    From lesson: Custom Marks and Filtering Tests

  48. If you apply @pytest.mark.database to a class, how does this affect the methods within that class?

    • The mark is ignored because it was not applied to the individual methods
    • Only the __init__ method of the class is marked
    • All test methods within the class automatically inherit the 'database' mark
    • The methods will fail unless they also have the decorator applied

    Answer: All test methods within the class automatically inherit the 'database' mark. Pytest marks applied to a class are inherited by all test methods within that class. The mark is not ignored, nor does it require individual decoration, and it certainly does not require the mark to be present for the test to pass.

    From lesson: Custom Marks and Filtering Tests

  49. You have tests marked with @pytest.mark.smoke and @pytest.mark.regression. How do you run only tests that are marked as 'smoke' but specifically EXCLUDE those that are 'regression'?

    • pytest -m 'smoke and not regression'
    • pytest -m 'smoke' --exclude 'regression'
    • pytest -m 'smoke' -k 'not regression'
    • pytest -m 'smoke' !regression

    Answer: pytest -m 'smoke and not regression'. Pytest supports logical expressions in the -m flag, allowing for complex selection using 'and', 'or', and 'not'. Option 1 is the correct syntax. The other options use invalid command-line flag structures for pytest.

    From lesson: Custom Marks and Filtering Tests

  50. Why is it recommended to add a description to a mark definition in the pytest.ini file?

    • It is required by the pytest runtime to execute the tests
    • It allows other developers to see the purpose of the mark when running 'pytest --markers'
    • It causes the test to include the description in the XML output files
    • It prevents the test suite from crashing if a marker is missing

    Answer: It allows other developers to see the purpose of the mark when running 'pytest --markers'. The 'pytest --markers' command displays the documentation provided in the configuration file, making it easier for teams to understand the intent of custom markers. The other options are incorrect as the description does not influence runtime execution, XML outputs, or crash handling.

    From lesson: Custom Marks and Filtering Tests

  51. When is the condition provided to @pytest.mark.skipif evaluated?

    • During the test execution phase
    • Immediately when the test is collected
    • After all setup fixtures have run
    • At the end of the test session

    Answer: Immediately when the test is collected. Conditions in skipif are evaluated during collection, which is why they cannot access data produced by fixtures. Option 0 and 2 are wrong because those happen post-collection; option 3 is too late.

    From lesson: Skipping Tests — skip and skipif

  52. What is the primary difference between @pytest.mark.skip and pytest.skip()?

    • There is no functional difference
    • Mark skip is for classes, function skip is for tests
    • Mark skip is applied at collection, while pytest.skip() is called at runtime
    • pytest.skip() requires a reason, while mark skip does not

    Answer: Mark skip is applied at collection, while pytest.skip() is called at runtime. The decorator is evaluated at collection time, whereas the function call happens inside the test body during execution. Options 0, 1, and 3 are incorrect as they misstate the flexibility and usage of these tools.

    From lesson: Skipping Tests — skip and skipif

  53. If you want to skip a test only when running on a specific Python version, what is the best practice?

    • Use @pytest.mark.skipif(sys.version_info < (3, 9), reason='Requires newer Python')
    • Use an if statement and call pytest.exit()
    • Hardcode the skip inside a try-except block
    • Use @pytest.mark.skipif(condition=True)

    Answer: Use @pytest.mark.skipif(sys.version_info < (3, 9), reason='Requires newer Python'). Using skipif with a conditional expression is the standard pytest approach. Option 1 stops the whole session, 2 is non-idiomatic, and 3 is not a conditional skip.

    From lesson: Skipping Tests — skip and skipif

  54. What happens if a test is skipped using @pytest.mark.skip?

    • The test is executed but marked as a failure
    • The test is not executed, but it appears as 's' in the output
    • The test is completely removed from the report
    • The test results in an error if the reason is missing

    Answer: The test is not executed, but it appears as 's' in the output. Skipped tests are reported as 's' (skipped) in the pytest output. Option 0 describes xfail, 2 is wrong because the report tracks it, and 3 is wrong because reason is optional.

    From lesson: Skipping Tests — skip and skipif

  55. Why might you choose @pytest.mark.xfail over @pytest.mark.skip?

    • To hide the test from the execution report entirely
    • To ensure the test is run but document that it is expected to fail
    • Because xfail is faster than skip
    • To force the test to always pass

    Answer: To ensure the test is run but document that it is expected to fail. Xfail is used when you know a test will fail but you still want to run it to track its status. Skip prevents the test from running at all. Options 0, 2, and 3 are fundamentally incorrect regarding the purpose of xfail.

    From lesson: Skipping Tests — skip and skipif

  56. When a test is marked with @pytest.mark.xfail and it unexpectedly passes (xpass), what is the default behavior in pytest?

    • The test is reported as a failure
    • The test is reported as an expected pass (xpass)
    • The test is ignored entirely
    • The test results in a SystemExit

    Answer: The test is reported as an expected pass (xpass). By default, pytest reports an xpass as a special 'xpass' outcome. Option 0 is incorrect because it only happens if strict=True is set. Option 2 is incorrect because the test still executes. Option 3 is irrelevant to the reporting mechanism.

    From lesson: Expected Failures — xfail

  57. Which of the following scenarios is the most appropriate use case for pytest.mark.xfail?

    • A feature is not yet implemented, so the test fails
    • A platform-specific bug exists that cannot be fixed until a third-party dependency is updated
    • The test takes too long to run on the CI server
    • The developer wants to prevent the test from running at all

    Answer: A platform-specific bug exists that cannot be fixed until a third-party dependency is updated. xfail is for tests that are known to fail due to external factors or deferred fixes. Option 0 is better handled by a 'skip' mark. Option 2 is a performance issue, not an expectation issue. Option 3 is explicitly solved by 'skip'.

    From lesson: Expected Failures — xfail

  58. What happens if a test is marked @pytest.mark.xfail(strict=True) and the test passes?

    • The test suite continues as if nothing happened
    • The test is reported as an xpass
    • The test is reported as a failure
    • The test is automatically skipped

    Answer: The test is reported as a failure. When strict=True, an unexpected pass is treated as a test failure. This is used to ensure developers clean up tests that no longer need the xfail status. The other options describe default behaviors, not strict mode behavior.

    From lesson: Expected Failures — xfail

  59. If you want to only mark a test as xfail if a specific condition is met (e.g., based on the Python version), how should you implement this?

    • Use an if-statement inside the test body to call pytest.xfail()
    • Pass a 'condition' argument to @pytest.mark.xfail
    • Use @pytest.mark.skipif instead
    • There is no way to conditionally mark a test as xfail

    Answer: Pass a 'condition' argument to @pytest.mark.xfail. The 'condition' argument (or boolean expression) inside @pytest.mark.xfail allows for dynamic marking. Option 0 is possible but less declarative than the decorator. Option 2 skips the test, which is a different outcome. Option 3 is false because the decorator is designed for this.

    From lesson: Expected Failures — xfail

  60. What is the primary difference between @pytest.mark.skip and @pytest.mark.xfail?

    • xfail runs the test, skip does not
    • skip runs the test, xfail does not
    • xfail always passes, skip always fails
    • There is no functional difference

    Answer: xfail runs the test, skip does not. xfail executes the code to check if it still fails (or if it has started passing), whereas skip stops the test runner from executing the code entirely. Options 1, 2, and 3 misrepresent the execution flow and the outcomes of these two markers.

    From lesson: Expected Failures — xfail

  61. If you are testing 'app.services.get_user' which calls 'app.db.query', where should you apply the @patch decorator?

    • @patch('app.services.query')
    • @patch('app.db.query')
    • @patch('app.services.db.query')
    • @patch('app.query')

    Answer: @patch('app.services.db.query'). You must patch where the name is looked up, which is 'app.services'. Options 0 and 1 target the wrong namespaces, and option 3 assumes an incorrect import path.

    From lesson: unittest.mock — MagicMock and patch

  62. What is the primary benefit of using autospec=True in a mock patch?

    • It automatically generates test data for your function arguments.
    • It ensures the mock raises an error if you call it with incorrect arguments or invalid attribute names.
    • It speeds up test execution by bypassing the real module's initialization.
    • It allows the mock to perform real network requests if the network is available.

    Answer: It ensures the mock raises an error if you call it with incorrect arguments or invalid attribute names.. autospec ensures the mock follows the signature of the object it replaces. The other options describe features unrelated to the mock's interface validation.

    From lesson: unittest.mock — MagicMock and patch

  63. How do you configure a mock to raise a ConnectionError the first time it is called and return a valid user object the second time?

    • Set return_value to [ConnectionError(), {'id': 1}]
    • Set side_effect to [ConnectionError, {'id': 1}]
    • Set return_value to ConnectionError and then update return_value to {'id': 1}
    • Set side_effect to a lambda function that raises an error.

    Answer: Set side_effect to [ConnectionError, {'id': 1}]. side_effect accepts an iterable; if an item is an exception class, it is raised. return_value would return the list itself. A lambda is less efficient for this specific sequence requirement.

    From lesson: unittest.mock — MagicMock and patch

  64. Why should you avoid patching objects inside the setup method of a test class?

    • Because setup runs before every test and might not properly clean up the patches.
    • Because patches only work when applied as decorators.
    • Because setup methods are deprecated in pytest.
    • Because patching in setup prevents the use of pytest fixtures.

    Answer: Because setup runs before every test and might not properly clean up the patches.. Patches in setup require careful management to avoid leakage. Decorators and context managers are preferred in pytest for isolation. Pytest does not deprecate setup, but fixtures are superior.

    From lesson: unittest.mock — MagicMock and patch

  65. Which of these assertions correctly verifies that a mocked function was called with specific keyword arguments?

    • mock.assert_called_with(id=5)
    • mock.called_with(id=5)
    • assert mock.call_args == id(5)
    • mock.verify_args(id=5)

    Answer: mock.assert_called_with(id=5). assert_called_with is the standard method for argument verification. called_with and verify_args are not valid methods, and checking call_args directly is less readable and error-prone.

    From lesson: unittest.mock — MagicMock and patch

  66. Which of the following best describes the primary advantage of the 'mocker' fixture over the standard 'unittest.mock.patch' decorator?

    • It provides a higher execution speed for the test suite.
    • It automatically cleans up patches after the test finishes, reducing boilerplate code.
    • It allows mocking of private methods that 'unittest' cannot reach.
    • It prevents tests from failing due to race conditions.

    Answer: It automatically cleans up patches after the test finishes, reducing boilerplate code.. The mocker fixture manages the lifecycle of patches automatically via pytest's teardown process. Option 0 is false as performance is similar. Option 2 is false as the underlying patch logic is identical. Option 3 is false as race conditions are outside the scope of mocking.

    From lesson: pytest-mock — mocker fixture

  67. You have a module 'app.services' that uses 'requests.get'. Where should you place the mocker path for testing?

    • mocker.patch('requests.get')
    • mocker.patch('app.services.requests.get')
    • mocker.patch('requests.api.get')
    • mocker.patch('app.services.requests.api.get')

    Answer: mocker.patch('app.services.requests.get'). In Python, you must mock the object where it is imported and used, not where it is defined. Option 0 and 2 fail because they mock the origin. Option 3 is an incorrect pathing. Option 1 correctly targets the lookup location in the service.

    From lesson: pytest-mock — mocker fixture

  68. What is the primary benefit of using 'autospec=True' when creating a mock?

    • It allows the mock to run as fast as compiled code.
    • It automatically records all calls made to the function.
    • It creates a mock object that has the same attributes and methods as the object being replaced.
    • It ensures the mock returns the same value as the real function.

    Answer: It creates a mock object that has the same attributes and methods as the object being replaced.. Autospec verifies the mock object matches the interface of the target, catching signature mismatches. Option 0 is nonsense. Option 1 is standard mock behavior. Option 3 is incorrect as the mock does not execute the original logic by default.

    From lesson: pytest-mock — mocker fixture

  69. When testing a function that performs a network request, why might you prefer 'mocker.patch' over creating a manual Mock class?

    • It is mandatory for all network tests in pytest.
    • It allows for easier assertion of how many times the dependency was called and with what arguments.
    • It automatically handles JSON serialization of the arguments.
    • It prevents the need for writing test assertions entirely.

    Answer: It allows for easier assertion of how many times the dependency was called and with what arguments.. Mocker makes inspection of call counts and arguments trivial using assert_called_with. Option 0 is false; it is a convenience. Option 2 is false. Option 3 is false; you still must assert outcomes.

    From lesson: pytest-mock — mocker fixture

  70. If you need to verify that a mock was called twice with specific arguments, which method should you use?

    • mock_obj.assert_called_twice_with(args)
    • mock_obj.assert_has_calls([call(args), call(args)])
    • mock_obj.verify_calls(2, args)
    • mock_obj.count_calls(2)

    Answer: mock_obj.assert_has_calls([call(args), call(args)]). assert_has_calls allows verifying an ordered sequence of calls. Option 0 does not exist in standard unittest.mock. Option 2 and 3 are not valid API methods.

    From lesson: pytest-mock — mocker fixture

  71. You want to mock 'requests.get' inside 'myapp.api'. Which path should you provide to patch()?

    • patch('requests.get')
    • patch('myapp.api.requests.get')
    • patch('myapp.api.get')
    • patch('requests.get.myapp.api')

    Answer: patch('myapp.api.requests.get'). Correct: You must patch where the name is looked up, which is inside your module. Option 0 patches the original library, which won't affect the import already inside 'myapp.api'. Option 2 assumes 'get' was imported directly. Option 3 is an invalid path structure.

    From lesson: Patching — patch, patch.object

  72. What is the primary difference between patch() and patch.object()?

    • patch.object is faster than patch
    • patch.object is only for methods, patch is for functions
    • patch requires a string path, patch.object takes the actual object
    • patch.object cannot be used as a decorator

    Answer: patch requires a string path, patch.object takes the actual object. Correct: patch() takes a string path to resolve the object, while patch.object takes the object instance/class directly. Option 0 is false. Option 1 is false, both can handle functions or classes. Option 3 is false, both work as decorators.

    From lesson: Patching — patch, patch.object

  73. When using a decorator for patching, in what order are the mock objects passed to your test function?

    • In the order they are defined from innermost to outermost
    • In the order they are defined from outermost to innermost
    • They are not passed to the test function automatically
    • They are passed alphabetically by module name

    Answer: In the order they are defined from innermost to outermost. Correct: Decorators are applied from bottom to top, meaning the innermost decorator's mock is passed as the first argument. Option 1 is backwards. Option 2 is false as they are indeed passed. Option 3 is false.

    From lesson: Patching — patch, patch.object

  74. Why is it recommended to use patch as a context manager if you aren't using a decorator?

    • It makes the test code run faster
    • It prevents the need for an explicit stop() call
    • It allows mocking of private methods
    • It changes the return type of the mock object

    Answer: It prevents the need for an explicit stop() call. Correct: Using 'with patch(...) as m:' ensures that the patch is automatically cleaned up when the block exits. Option 0 is irrelevant. Option 2 is possible with both styles. Option 3 is false.

    From lesson: Patching — patch, patch.object

  75. If you mock a class using patch, what is the default return value when the mock is called?

    • A new MagicMock instance
    • None
    • The original class instance
    • A string representation of the class

    Answer: A new MagicMock instance. Correct: Mocking a class results in a MagicMock; when that mock is called (instantiated), it returns another MagicMock representing the instance. Option 1, 2, and 3 are incorrect behaviors of the mocking framework.

    From lesson: Patching — patch, patch.object

  76. You are testing a function that processes an image and saves it to a directory. Which approach best validates the full behavior?

    • Only assert the returned boolean indicating success.
    • Mock the filesystem and verify the file creation and return value.
    • Check only that the function does not raise an exception.
    • Check only the file existence on the disk after the test finishes.

    Answer: Mock the filesystem and verify the file creation and return value.. Option 1 fails to check if the file was actually saved. Option 3 ignores the result and the side effect. Option 4 is risky because it relies on real disk I/O. Option 2 is correct because it isolates the logic from the disk while verifying both the side effect (mock call) and the return value.

    From lesson: Side Effects and Return Values

  77. A test asserts a return value but ignores a side effect that modifies a shared object. What is the primary risk?

    • The test will fail intermittently due to race conditions.
    • The test will fail immediately if the return value is correct.
    • The test provides a false sense of security while the system state remains invalid.
    • Pytest will throw a warning about unasserted side effects.

    Answer: The test provides a false sense of security while the system state remains invalid.. If the side effect is the primary purpose of the function, verifying only the return value misses the logic failure. Option 1 is incorrect as standard tests are usually sequential. Option 4 is false as pytest does not monitor side effects automatically.

    From lesson: Side Effects and Return Values

  78. When using `monkeypatch` to replace a function, why is it safer than manually overriding a function object?

    • It is faster to execute.
    • It automatically reverses the change after the test, regardless of success or failure.
    • It allows you to skip the actual function call entirely.
    • It provides a better syntax for assertions.

    Answer: It automatically reverses the change after the test, regardless of success or failure.. Monkeypatch is designed to handle teardown automatically. Manual overrides persist across tests unless explicitly reverted, which is prone to error. The other options do not describe the primary benefit of the fixture's cleanup mechanism.

    From lesson: Side Effects and Return Values

  79. If a test function fails during an assertion of a side effect, what happens to the subsequent assertions in the same test?

    • They are executed but marked as skipped.
    • They are ignored because the test execution stops at the first failed assertion.
    • They are executed, and all results are reported.
    • The test runner attempts to recover the state.

    Answer: They are ignored because the test execution stops at the first failed assertion.. Pytest stops executing a test function as soon as an assertion fails. This is why testing the return value and the side effect together is important; if the return value check fails, you never reach the side effect check, potentially masking a secondary bug.

    From lesson: Side Effects and Return Values

  80. How should you test a function that has a side effect of incrementing a counter in a database?

    • Call the function, then query the database to verify the increment.
    • Mock the database increment method and verify it was called with the correct parameters.
    • Only check that the function returns the expected new count.
    • Use a fixture to reset the entire database before every individual assertion.

    Answer: Mock the database increment method and verify it was called with the correct parameters.. Mocking the interaction verifies that the function correctly triggered the specific side effect. Querying the database (Option 1) is a test of the database integration, not the function's logic. Option 3 ignores the side effect entirely. Option 4 is inefficient and unnecessary.

    From lesson: Side Effects and Return Values

  81. What happens if a block of code inside 'with pytest.raises(ValueError):' executes successfully without raising any error?

    • The test passes automatically.
    • The test fails because no exception was raised.
    • The test reports an unexpected exception error.
    • The test hangs indefinitely.

    Answer: The test fails because no exception was raised.. If no exception is raised, pytest explicitly fails the test. Option 0 is wrong because a failure is required. Option 2 is wrong because no exception occurred. Option 3 is wrong as pytest handles the termination.

    From lesson: Testing Exceptions — pytest.raises

  82. Which of the following is the correct way to capture an exception object for further inspection?

    • with pytest.raises(ZeroDivisionError) as exc_info:
    • with pytest.raises(ZeroDivisionError, capture=True) as exc_info:
    • exc_info = pytest.raises(ZeroDivisionError)
    • with pytest.raises(ZeroDivisionError) -> exc_info:

    Answer: with pytest.raises(ZeroDivisionError) as exc_info:. Using 'as' assigns an ExceptionInfo object to the variable, which allows checking the message or traceback. Options 1, 2, and 3 use incorrect syntax for the pytest API.

    From lesson: Testing Exceptions — pytest.raises

  83. You want to ensure that a function raises a 'RuntimeError' with the message 'Connection failed'. How do you do this properly?

    • with pytest.raises(RuntimeError, message='Connection failed'):
    • with pytest.raises(RuntimeError, match='Connection failed'):
    • with pytest.raises(RuntimeError): assert 'Connection failed' in str(e)
    • with pytest.raises(RuntimeError): assert_message('Connection failed')

    Answer: with pytest.raises(RuntimeError, match='Connection failed'):. The 'match' parameter uses regex to check the exception message. Option 0 is a non-existent parameter. Option 2 is inefficient compared to 'match', and Option 3 is not a standard pytest function.

    From lesson: Testing Exceptions — pytest.raises

  84. Why is it best practice to keep the code inside the 'with pytest.raises' block minimal?

    • To improve execution speed by a few milliseconds.
    • To avoid capturing exceptions that occur in unrelated code lines.
    • To make the test pass faster in parallel mode.
    • Because pytest cannot handle more than 5 lines in a block.

    Answer: To avoid capturing exceptions that occur in unrelated code lines.. If you put too much code in the block, you might accidentally catch an exception you didn't intend to test. Options 0, 2, and 3 are incorrect as they do not relate to the logic of exception scoping.

    From lesson: Testing Exceptions — pytest.raises

  85. When using 'exc_info = pytest.raises(...):', how do you access the exception instance itself?

    • exc_info.exception
    • exc_info.value
    • exc_info.get_instance()
    • exc_info.error

    Answer: exc_info.value. In pytest, the ExceptionInfo object stores the actual exception instance in the '.value' attribute. The other attributes listed do not exist or are not the correct way to retrieve the exception instance.

    From lesson: Testing Exceptions — pytest.raises

  86. What is the primary function of the @pytest.mark.asyncio decorator?

    • It converts a synchronous function into an asynchronous one.
    • It instructs the pytest-asyncio plugin to execute the function as a coroutine.
    • It tells the operating system to allocate more memory to the test process.
    • It forces the test to run in a separate thread instead of the event loop.

    Answer: It instructs the pytest-asyncio plugin to execute the function as a coroutine.. Option 2 is correct because the decorator registers the test with the plugin, which handles the event loop setup. Option 1 is wrong because it doesn't change the function type. Option 3 is unrelated to memory allocation. Option 4 is wrong because async tests run within the event loop, not necessarily a separate thread.

    From lesson: Testing Async Code — pytest-asyncio

  87. If you have an async fixture, how should you use it in an async test?

    • By calling the fixture function as a standard synchronous function.
    • By manually creating a new event loop inside the test function.
    • By requesting the fixture as an argument in the test function signature.
    • By wrapping the test function in a try-finally block to manage the fixture.

    Answer: By requesting the fixture as an argument in the test function signature.. Option 3 is correct because pytest handles the injection and awaiting of async fixtures automatically. Option 1 fails because calling it synchronously returns the coroutine object. Option 2 is redundant as the plugin handles the loop. Option 4 is unnecessary boilerplate code.

    From lesson: Testing Async Code — pytest-asyncio

  88. Why might a test pass locally but fail in CI when testing async code?

    • Because CI environments often run tests in alphabetical order.
    • Because of race conditions caused by implicit event loop dependencies.
    • Because pytest-asyncio requires a specific browser to be installed.
    • Because async code is not supported by standard CI runners.

    Answer: Because of race conditions caused by implicit event loop dependencies.. Option 2 is correct; asynchronous tests often rely on implicit shared state or loop settings that differ in varied environments, causing race conditions. Option 1 is standard behavior for all tests. Option 3 is incorrect as the plugin is framework-agnostic. Option 4 is false, as CI environments support async test execution.

    From lesson: Testing Async Code — pytest-asyncio

  89. When using the 'asyncio_mode = auto' configuration, what happens to async functions?

    • They are automatically ignored by the test collection process.
    • They must be explicitly marked with @pytest.mark.asyncio or they will fail.
    • They are automatically treated as async tests without needing the decorator.
    • They are converted to run on a multi-threaded pool by default.

    Answer: They are automatically treated as async tests without needing the decorator.. Option 2 is correct because 'auto' mode detects 'async def' functions and treats them as asyncio tests automatically. Option 1 is wrong as they are collected. Option 3 is a common misinterpretation; the mode removes the need for the decorator. Option 4 is incorrect as pytest-asyncio does not default to thread pooling for async tests.

    From lesson: Testing Async Code — pytest-asyncio

  90. What happens if you use 'time.sleep(1)' inside an async test method?

    • The event loop continues to process other tasks during the sleep.
    • The test will fail immediately with a TimeoutError.
    • The entire test process blocks, pausing all other concurrent tasks.
    • The test automatically converts the sleep to an awaitable operation.

    Answer: The entire test process blocks, pausing all other concurrent tasks.. Option 2 is correct; 'time.sleep' is a blocking call that halts the thread, which stops the event loop from advancing any other pending tasks. Option 1 is incorrect because it is blocking. Option 3 is incorrect because the test doesn't necessarily time out. Option 4 is incorrect as standard libraries are not magically patched by pytest.

    From lesson: Testing Async Code — pytest-asyncio

  91. If your coverage report shows 100% coverage, what does that confirm?

    • Every line of your code has been executed during the test suite run.
    • Your code is free of logical bugs and edge case errors.
    • Your tests cover every possible input combination.
    • The code is production-ready and performance-optimized.

    Answer: Every line of your code has been executed during the test suite run.. 100% line coverage means every line was executed at least once. It does not prove correctness (logic), sufficiency (edge cases), or readiness, making the other options false.

    From lesson: Coverage with pytest-cov

  92. What is the primary difference between line coverage and branch coverage?

    • Line coverage requires fewer tests to achieve 100% than branch coverage.
    • Branch coverage tracks whether both 'True' and 'False' outcomes for every decision point were executed.
    • Line coverage is only available in external plugins, while branch coverage is built into pytest.
    • Branch coverage is mandatory for all production-grade software.

    Answer: Branch coverage tracks whether both 'True' and 'False' outcomes for every decision point were executed.. Branch coverage ensures that every path through a control structure (like if/else) is traversed. Line coverage just checks if the line is hit; branch coverage is stricter and more informative.

    From lesson: Coverage with pytest-cov

  93. Why is it recommended to use the '--cov' flag in conjunction with a specific directory or package?

    • To speed up the execution time of individual tests.
    • To force the interpreter to use a specific version of the code.
    • To restrict the measurement scope to your own application code rather than dependencies.
    • To allow the coverage report to be exported as a PDF file.

    Answer: To restrict the measurement scope to your own application code rather than dependencies.. Specifying a source restricts the coverage tool to your project files, preventing it from reporting on installed libraries in your virtual environment, which would pollute the report.

    From lesson: Coverage with pytest-cov

  94. When a line of code is marked as 'missing' in a report, what does that usually imply?

    • The code is unreachable and should be deleted immediately.
    • The code logic is too complex for the coverage tool to parse.
    • No test case in your suite triggered that specific line of code during execution.
    • There is a syntax error preventing the test from running that line.

    Answer: No test case in your suite triggered that specific line of code during execution.. A 'missing' line simply means the test runner did not pass through that line during the test cycle. It is not necessarily unreachable, nor is it a syntax error.

    From lesson: Coverage with pytest-cov

  95. How can you permanently exclude specific files or directories from your coverage report?

    • By renaming the files to start with an underscore.
    • By configuring the '[run]' section in a '.coveragerc' file or project config file.
    • By deleting the files before running the coverage command.
    • By adding a comment like '# no-coverage' to the top of every file.

    Answer: By configuring the '[run]' section in a '.coveragerc' file or project config file.. Using a configuration file like '.coveragerc' is the standard way to define persistent settings such as omissions, whereas the other options are either temporary, incorrect, or poor practice.

    From lesson: Coverage with pytest-cov

  96. What is the primary benefit of using TestClient over calling route functions directly?

    • It bypasses the entire FastAPI dependency injection system
    • It simulates the full request/response lifecycle including middleware and routing
    • It forces the test to run faster by avoiding the event loop
    • It automatically deploys the application to a staging server

    Answer: It simulates the full request/response lifecycle including middleware and routing. TestClient allows you to test the app as it would behave in production, processing middleware, validation, and dependency injection. Option 0 is false, it uses DI; Option 2 is false, it still uses the event loop; Option 3 is false, it is strictly local.

    From lesson: Testing FastAPI with TestClient

  97. How should you handle an external database dependency when running a suite of tests?

    • Connect to the live production database to ensure real data validity
    • Use a global variable to track the state between tests
    • Use FastAPI's dependency_overrides to replace the real DB with a test database
    • Delete the database manually after every single test case

    Answer: Use FastAPI's dependency_overrides to replace the real DB with a test database. dependency_overrides allow for clean, surgical replacement of services during testing. Connecting to production (0) is dangerous, global variables (1) lead to race conditions, and manual deletion (3) is inefficient compared to fixture-based cleanup.

    From lesson: Testing FastAPI with TestClient

  98. When a route requires an 'Authorization' header, how do you provide it in a TestClient request?

    • By setting the environment variable in the OS
    • By passing it in the 'headers' argument of the request method
    • By modifying the app instance's global configuration
    • By manually creating an HTTP request object and injecting it

    Answer: By passing it in the 'headers' argument of the request method. TestClient request methods accept a 'headers' dictionary that matches the standard HTTP interface. Modifying global state (2) is risky, and environment variables (0) are not granular enough for specific headers.

    From lesson: Testing FastAPI with TestClient

  99. Why would a test that passes in isolation fail when run as part of a larger test suite?

    • Because pytest runs tests in alphabetical order by default
    • Because of shared mutable state like a database or application singleton
    • Because TestClient is not thread-safe
    • Because FastAPI routes are memoized by the test runner

    Answer: Because of shared mutable state like a database or application singleton. Shared mutable state is the primary cause of flaky tests. Option 0 is a red herring regarding order, Option 2 is incorrect as TestClient handles concurrency, and Option 3 is false.

    From lesson: Testing FastAPI with TestClient

  100. What is the correct way to handle a test that needs to reset the application state after execution?

    • A standard function call at the end of the test
    • A pytest fixture using 'yield' for setup and teardown
    • A try/except block wrapping the test logic
    • A separate test specifically written to delete data

    Answer: A pytest fixture using 'yield' for setup and teardown. Fixtures with yield are the standard pytest idiom for setup/teardown. A standard function call (0) won't run if the test fails, a try/except (2) is overly verbose, and a separate test (3) is unreliable.

    From lesson: Testing FastAPI with TestClient

  101. Why is it recommended to use a 'function' scope for database session fixtures in pytest?

    • It is the only way to make the tests run faster.
    • It ensures that each test starts with a clean, isolated database state.
    • It is required by SQLAlchemy for connection pooling.
    • It prevents pytest from running tests in parallel.

    Answer: It ensures that each test starts with a clean, isolated database state.. Function scope ensures the fixture runs for every individual test, providing a fresh transaction. Option 0 is wrong because function scope is often slower than session scope. Option 2 is incorrect as it is a pytest convention, not a SQLAlchemy requirement. Option 3 is false as scope does not dictate parallelism capabilities.

    From lesson: Testing SQLAlchemy — Database Fixtures

  102. What is the primary purpose of using 'yield' in a pytest database fixture?

    • To return multiple database connections at once.
    • To pause the test execution until the database is ready.
    • To provide a mechanism to perform teardown actions after the test completes.
    • To convert the database session into a generator object.

    Answer: To provide a mechanism to perform teardown actions after the test completes.. The 'yield' statement acts as a breakpoint; code before 'yield' is setup, and code after is teardown. Option 0 and 3 are incorrect technical definitions. Option 1 is wrong because pytest handles the test start once the fixture yields.

    From lesson: Testing SQLAlchemy — Database Fixtures

  103. When testing database code, why is an in-memory SQLite database often preferred?

    • It supports all complex database features exactly like a production server.
    • It is highly persistent and keeps data across different test runs.
    • It provides rapid setup and teardown speeds without disk I/O.
    • It allows multiple test runners to write to the same file.

    Answer: It provides rapid setup and teardown speeds without disk I/O.. In-memory databases exist only in RAM, making them extremely fast for unit tests. Option 0 is false because SQLite lacks many production features (e.g., custom types). Option 1 is false (it is ephemeral). Option 3 is false (it does not resolve concurrency).

    From lesson: Testing SQLAlchemy — Database Fixtures

  104. How does wrapping a test in a transaction and rolling it back benefit a test suite?

    • It makes the test run significantly faster by avoiding commit operations.
    • It ensures that even if a test fails, the database remains in its initial state.
    • It forces the database to write logs to the hard drive for debugging.
    • It automatically updates the SQLAlchemy model schema to match the database.

    Answer: It ensures that even if a test fails, the database remains in its initial state.. Rollbacks ensure test isolation by removing any changes made during the test. Option 0 is not the primary benefit. Option 2 is irrelevant to the rollback process. Option 3 is false as transactions do not alter schemas.

    From lesson: Testing SQLAlchemy — Database Fixtures

  105. If your tests are failing because of foreign key constraint errors during cleanup, what should you do?

    • Delete the database entirely and recreate it for every single assertion.
    • Use a fixture that clears tables in the correct order or disables foreign key checks.
    • Remove all foreign keys from the production database schema.
    • Ignore the errors, as they do not affect the outcome of the assertions.

    Answer: Use a fixture that clears tables in the correct order or disables foreign key checks.. Foreign keys enforce dependencies; clearing tables out of order causes errors. Option 0 is inefficient. Option 2 is dangerous for production. Option 3 is wrong because ignoring test errors leads to unreliable test suites.

    From lesson: Testing SQLAlchemy — Database Fixtures

  106. What is the primary goal of the 'Red' phase in the TDD cycle when using pytest?

    • To ensure the application reaches 100% code coverage.
    • To verify that the test fails for the correct reason before writing implementation.
    • To refactor the existing code for better performance.
    • To configure the environment for continuous integration.

    Answer: To verify that the test fails for the correct reason before writing implementation.. The 'Red' phase is about confirming the test fails, which proves the test is valid and that the feature is indeed missing. Other options are incorrect because coverage, refactoring, and CI configuration are not the primary focus of this specific cycle phase.

    From lesson: Test-Driven Development (TDD)

  107. If you are following TDD and your new test passes immediately, what should you do?

    • Commit the code and move to the next feature.
    • Add more test cases to ensure the test is too broad.
    • Delete the test and write a different test to ensure you can make it fail.
    • Ignore it, as pass-on-first-run is the ideal scenario.

    Answer: Delete the test and write a different test to ensure you can make it fail.. If a test passes immediately, you have no proof the test is actually testing what you think it is (it might be a false positive). You must delete it and write a test that fails to confirm the test works. The other options ignore the risk of a false positive.

    From lesson: Test-Driven Development (TDD)

  108. Which of the following best describes the 'Refactor' phase in a pytest-driven workflow?

    • Adding new features while the tests are still passing.
    • Changing the implementation to improve design without altering behavior.
    • Updating the tests to match the new, improved implementation.
    • Rewriting the test suite to use fixtures instead of setup methods.

    Answer: Changing the implementation to improve design without altering behavior.. Refactoring is strictly about improving internal code quality (DRY, readability) while maintaining existing behavior, verified by tests. Other options involve changing requirements or tests, which violates the intent of the refactor phase.

    From lesson: Test-Driven Development (TDD)

  109. When using pytest in TDD, why should you avoid testing internal private methods directly?

    • Pytest makes it impossible to access private methods.
    • Testing internal implementation details makes tests fragile and resistant to refactoring.
    • Private methods are usually too simple to require testing.
    • Public methods already cover 100% of the logic found in private methods.

    Answer: Testing internal implementation details makes tests fragile and resistant to refactoring.. Tests should verify behavior through public APIs; binding tests to private methods forces you to update tests whenever you change internal structure, even if the public output remains the same. The other options are either false (pytest can access private methods) or logical fallacies.

    From lesson: Test-Driven Development (TDD)

  110. Why is it important to keep pytest tests fast in a TDD cycle?

    • So that code coverage reports generate more quickly.
    • Because TDD relies on a short, frequent feedback loop.
    • To allow for more complex assertion logic in each test.
    • Because pytest will crash if a test takes longer than one second.

    Answer: Because TDD relies on a short, frequent feedback loop.. TDD depends on running tests constantly; if tests are slow, the developer loses focus and disrupts the flow. The other options are incorrect: coverage speed is not the priority, fast tests do not enable more complex logic, and pytest does not crash on slow tests.

    From lesson: Test-Driven Development (TDD)

  111. Why is 'function' scope preferred over 'module' scope for fixtures dealing with shared mutable state?

    • It is faster because function scope fixtures are cached permanently.
    • It ensures that state modifications made in one test do not impact the assertions of another.
    • It allows pytest to parallelize tests across different CPU cores more effectively.
    • It is required by the pytest framework for all fixtures by default.

    Answer: It ensures that state modifications made in one test do not impact the assertions of another.. Option 2 is correct because isolation prevents test pollution. Option 1 is wrong because function scope is the least cached. Option 3 is wrong because scope doesn't dictate parallelization. Option 4 is wrong because the default scope is 'function', but you can specify others.

    From lesson: Test Isolation and State

  112. What is the primary benefit of using the 'yield' keyword in a pytest fixture?

    • It allows the fixture to return multiple values to the test function.
    • It converts the fixture into a generator, allowing for explicit teardown code after the test execution.
    • It forces the test function to run in a separate process for better isolation.
    • It automatically mocks the return value of the function being tested.

    Answer: It converts the fixture into a generator, allowing for explicit teardown code after the test execution.. Option 2 is correct as it enables the cleanup phase. Option 1 is wrong because yield only yields once per fixture execution. Option 3 is wrong because yield has no effect on process isolation. Option 4 is wrong as it relates to mocking, not lifecycle management.

    From lesson: Test Isolation and State

  113. You have a test that modifies a configuration file. What should you do to ensure test isolation?

    • Append the changes and revert them manually at the end of the test function.
    • Use a fixture that copies the file to a temporary directory and restores it after the test.
    • Mark the test with @pytest.mark.serial so it runs alone.
    • Only run the test if the configuration file already exists on the system.

    Answer: Use a fixture that copies the file to a temporary directory and restores it after the test.. Option 2 is the best practice using tmp_path/tmpdir to ensure no collateral damage. Option 1 is risky if the test crashes before reverting. Option 3 does not solve state corruption. Option 4 limits testing capability.

    From lesson: Test Isolation and State

  114. If Test A modifies a database and Test B checks the database count, why might they fail when running together but pass individually?

    • Because of a race condition in the operating system's filesystem.
    • Because the tests are not isolated, and Test B is reading the side effects of Test A.
    • Because pytest uses alphabetical ordering, which causes a buffer overflow.
    • Because Test A is not decorated with the correct module scope.

    Answer: Because the tests are not isolated, and Test B is reading the side effects of Test A.. Option 2 is correct; shared state is the root cause of non-deterministic behavior. Option 1 is incorrect as this is a logic dependency, not an OS issue. Option 3 is nonsense. Option 4 is incorrect as scope is not the reason for test interdependence.

    From lesson: Test Isolation and State

  115. How does the 'tmp_path' fixture improve test isolation compared to using a hardcoded directory like '/tmp/test_dir'?

    • It automatically deletes the folder every time the user logs out of the machine.
    • It ensures every test gets a unique subdirectory, preventing collisions and partial state contamination.
    • It runs the test with administrative privileges to prevent file access errors.
    • It encrypts the temporary data to prevent other tests from reading it.

    Answer: It ensures every test gets a unique subdirectory, preventing collisions and partial state contamination.. Option 2 is correct as unique paths per test are the key to isolation. Option 1 is false. Option 3 is false and dangerous. Option 4 is false as isolation is about logic independence, not security.

    From lesson: Test Isolation and State

  116. When implementing the AAA pattern, where should you place the primary logic that triggers the behavior under test?

    • Inside the Arrange section
    • Inside the Act section
    • Inside the Assert section
    • Inside the Teardown section

    Answer: Inside the Act section. The Act section is designated for calling the method or function being tested. Arrange is for setup, and Assert is for verification; putting the logic elsewhere violates the clear structure required for readability.

    From lesson: Testing Patterns — AAA, Factory

  117. What is the primary benefit of using a Factory pattern within a pytest suite?

    • To ensure every test creates a unique database connection
    • To abstract complex object construction and reduce code duplication
    • To automatically generate assertions for every created object
    • To replace the need for pytest fixtures entirely

    Answer: To abstract complex object construction and reduce code duplication. Factories are used to encapsulate complex object creation, making tests cleaner. They do not replace fixtures, nor should they handle assertions, and they definitely shouldn't be used to manage database connections globally.

    From lesson: Testing Patterns — AAA, Factory

  118. If your 'Arrange' phase is becoming excessively long, what is the best practice to keep the test readable?

    • Move the setup code into the 'Act' phase
    • Create a dedicated fixture to handle the setup complexity
    • Skip the 'Arrange' phase and use default global state
    • Include the assertion logic within the setup code

    Answer: Create a dedicated fixture to handle the setup complexity. Fixtures allow you to move setup logic outside the test body, keeping it concise. Moving setup to Act or Assert ruins the test structure, and skipping Arrange is rarely possible in meaningful tests.

    From lesson: Testing Patterns — AAA, Factory

  119. Which of the following is a symptom that your AAA test is incorrectly structured?

    • The test has exactly one action statement
    • The test uses multiple assertions to check related outcomes
    • You have multiple 'Act' calls separated by logic that should be in the setup
    • The test depends on a fixture to provide input data

    Answer: You have multiple 'Act' calls separated by logic that should be in the setup. An AAA test should generally have one logical 'Act'. If you have multiple actions separated by setup-like logic, the test is likely doing too much and should be broken down into separate tests.

    From lesson: Testing Patterns — AAA, Factory

  120. Why should you avoid performing 'Assert' logic inside a factory function?

    • Because factories are restricted from importing the pytest module
    • Because it couples the creation of test data to a specific verification outcome
    • Because factory functions return a generator instead of an object
    • Because pytest will crash if an assertion fails inside a factory

    Answer: Because it couples the creation of test data to a specific verification outcome. Factories should be reusable for different scenarios. Assertions inside a factory lock that factory into one specific test case, which breaks the purpose of having a reusable creation helper.

    From lesson: Testing Patterns — AAA, Factory

  121. When designing a test suite, why is it considered better to use dependency injection via fixtures rather than calling setup/teardown functions directly?

    • It forces the test to run in a specific alphabetical order.
    • It allows fixtures to manage their own scope and lifecycle automatically, preventing state leakage.
    • It makes the test code faster by bypassing the need for object instantiation.
    • It is the only way to avoid using assertions in a test file.

    Answer: It allows fixtures to manage their own scope and lifecycle automatically, preventing state leakage.. Fixture injection enables automatic setup/teardown and scoping (e.g., session vs. function). Calling functions directly leads to manual cleanup, which is error-prone. The other options are incorrect because fixtures don't affect order, don't necessarily increase speed, and don't restrict assertion usage.

    From lesson: Testing Interview Questions

  122. What is the primary benefit of using @pytest.mark.parametrize?

    • It automatically generates documentation for the test functions.
    • It prevents the test from failing if the inputs are incorrect.
    • It allows you to run the same test logic against multiple datasets without duplicating code.
    • It increases the test coverage score in the coverage report.

    Answer: It allows you to run the same test logic against multiple datasets without duplicating code.. Parametrization promotes DRY (Don't Repeat Yourself) principles by separating data from logic. It does not automatically document code, mask errors, or magically improve coverage metrics.

    From lesson: Testing Interview Questions

  123. What happens if a test function has a yield fixture, and an exception is raised during the test?

    • The fixture teardown code after the yield will still execute.
    • The test runner crashes immediately and leaves the environment in an inconsistent state.
    • The fixture teardown is skipped to preserve the state for debugging.
    • The test is automatically retried by the pytest runner.

    Answer: The fixture teardown code after the yield will still execute.. Pytest guarantees that code after the 'yield' statement in a fixture executes regardless of whether the test passed or raised an exception. This is essential for proper resource cleanup. The other options describe incorrect behaviors.

    From lesson: Testing Interview Questions

  124. Which of the following describes the most effective way to test code that interacts with an external API?

    • Send real requests to the API during every test run to ensure live connectivity.
    • Hardcode the API responses directly into the test file.
    • Mock the network layer to return deterministic responses, ensuring the test is fast and independent.
    • Check that the network is available before running the test suite.

    Answer: Mock the network layer to return deterministic responses, ensuring the test is fast and independent.. Mocking external dependencies ensures tests are deterministic, fast, and independent of external service uptime. Real network calls make tests flaky, while hardcoding responses inside the test function mixes concerns.

    From lesson: Testing Interview Questions

  125. Why should you avoid having tests that are dependent on the execution order of other tests?

    • Because pytest runs tests in random order by default.
    • Because dependent tests make it impossible to run tests in parallel or in isolation.
    • Because test execution order is determined by the operating system's CPU scheduler.
    • Because pytest requires a specific decorator to allow dependencies.

    Answer: Because dependent tests make it impossible to run tests in parallel or in isolation.. Independent tests allow for parallel execution and allow you to run individual tests without running the entire suite. Options A, C, and D are factually incorrect regarding how the pytest runner works.

    From lesson: Testing Interview Questions