
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/pytest","feed_url":"https:\/\/mathspp.com\/blog\/tags\/pytest.json","description":"Stay up-to-date with the articles on mathematics and programming that get published to mathspp.com.","author":{"name":"Rodrigo Gir\u00e3o Serr\u00e3o"},"items":[{"title":"TIL #105 \u2013 pytest selection arguments for failing tests","date_published":"2024-10-19T07:55:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/pytest-selection-arguments-for-failing-tests","url":"https:\/\/mathspp.com\/blog\/til\/pytest-selection-arguments-for-failing-tests","content_html":"<p>Today I learned about 5 useful pytest options that let me control what tests to run with respect to failing tests.<\/p>\n\n<h2 id=\"pytest-selection-arguments-for-failing-tests\">pytest selection arguments for failing tests<a href=\"#pytest-selection-arguments-for-failing-tests\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Florian Bruhin shared a pytest tip on X \/ Twitter the other day regarding command line options that pytest accepts and that control how pytest handles failed tests.\nHe shared the following <em>very<\/em> illustrative diagram:<\/p>\n<figure class=\"image-caption\"><img title=\"Diagram by Florian.\" alt=\"Diagram that explains visually how the pytest options `--last-failed`, `--failed-first`, `--new-first`, `--stepwise`, and `--maxfail` work. The visual explanation is done by representing tests as coloured circles, with failing tests represented in red and passing tests represented in green. Then, test runs are represented as sequences of tests connected by a line.\" src=\"\/user\/pages\/02.blog\/04.til\/105.pytest-selection-arguments-for-failing-tests\/_diagram.webp\"><figcaption class=\"\">Diagram by Florian.<\/figcaption><\/figure><p>I think the diagram is so good that I could essentially stop the article here and we all would've understood the options.\nBut I'll be just a little bit more verbose and explain how each option works.<\/p>\n<h3 id=\"maxfail\"><code>--maxfail<\/code><a href=\"#maxfail\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>Create the following file <code>test.py<\/code> with 4 failing tests:<\/p>\n<pre><code class=\"language-py\">def test_1():\n    assert False\n\ndef test_2():\n    assert False\n\ndef test_3():\n    assert False\n\ndef test_4():\n    assert False<\/code><\/pre>\n<p>If you run the tests with <code>pytest test.py<\/code> you get 4 failing tests. Duh.\nIf you use the option <code>--maxfail=n<\/code>, pytest will run until completion or until it finds <code>n<\/code> failures.\nRunning with <code>pytest test.py --maxfail=2<\/code> stops after <code>test_2<\/code> failed:<\/p>\n<pre><code>FAILED test.py::test_1 - assert False\nFAILED test.py::test_2 - assert False\n!!!!!!!!!! stopping after 2 failures !!!!!!!!!!!\n============== 2 failed in 0.04s ===============<\/code><\/pre>\n<h3 id=\"stepwise\"><code>--stepwise<\/code><a href=\"#stepwise\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>The option <code>--stepwise<\/code> stop at each failure and every time you rerun, it picks up from where it left off.\nStarting with the file from the previous example, if you run <code>pytest test.py --stepwise<\/code>, we stop immediately at the first failure:<\/p>\n<pre><code>FAILED test.py::test_1 - assert False\n! Interrupted: Test failed, continuing from this test next run. !\n============== 1 failed in 0.08s ===============<\/code><\/pre>\n<p>Note how pytest says we'll pick up from here when we rerun the tests.\nLet us go ahead and fix our first test:<\/p>\n<pre><code class=\"language-py\">def test_1():\n    assert True<\/code><\/pre>\n<p>We rerun pytest with <code>pytest test.py --stepwise<\/code> and we go up to test 2:<\/p>\n<pre><code>test.py .F\nFAILED test.py::test_2 - assert False\n! Interrupted: Test failed, continuing from this test next run. !\n========= 1 failed, 1 passed in 0.08s ==========<\/code><\/pre>\n<p>Note that pytest says that we passed one test (<code>test_1<\/code>, which was fixed) and that we failed one test (<code>test_2<\/code>).<\/p>\n<p>If we attempt to fix it (but still fail), when we rerun pytest with <code>pytest test.py --stepwise<\/code> we start from test 2 and it will fail again:<\/p>\n<pre><code>FAILED test.py::test_2 - assert False\n! Interrupted: Test failed, continuing from this test next run. !\n======= 1 failed, 1 deselected in 0.08s ========<\/code><\/pre>\n<p>Now, we don't even run <code>test_1<\/code> because we're already past it.\nWe tried rerunning <code>test_2<\/code> but it still failed.<\/p>\n<p>Let's now fix <code>test_2<\/code>:<\/p>\n<pre><code class=\"language-py\">def test_2():\n    assert True<\/code><\/pre>\n<p>Rerunning with <code>pytest test.py --stepwise<\/code> skips <code>test_1<\/code>, retries <code>test_2<\/code> and goes up to <code>test_3<\/code>:<\/p>\n<pre><code>FAILED test.py::test_3 - assert False\n! Interrupted: Test failed, continuing from this test next run. !\n== 1 failed, 1 passed, 1 deselected in 0.08s ===<\/code><\/pre>\n<p>Now, if we clear the pytest cache with <code>rm -rf .pytest_cache<\/code> and rerun with <code>pytest test.py --stepwise<\/code>, we see that we run the first three tests, stopping at <code>test_3<\/code> because that...<\/p>","summary":"Today I learned about 5 useful pytest options that let me control what tests to run with respect to failing tests.","date_modified":"2025-10-20T22:34:56+02:00","tags":["productivity","programming","python","pytest"],"image":"\/user\/pages\/02.blog\/04.til\/105.pytest-selection-arguments-for-failing-tests\/thumbnail.webp"},{"title":"TIL #095 \u2013 better test parametrisation in pytest","date_published":"2024-04-22T17:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/better-test-parametrisation-in-pytest","url":"https:\/\/mathspp.com\/blog\/til\/better-test-parametrisation-in-pytest","content_html":"<p>Today I learned how to use named tuples to improve readability and flexibility of test parametrisations in pytest.<\/p>\n\n<h2 id=\"better-test-parametrisation-in-pytest\">Better test parametrisation in pytest<a href=\"#better-test-parametrisation-in-pytest\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Today I attended a <a href=\"https:\/\/pretalx.com\/pyconde-pydata-2024\/talk\/DSFWRC\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">pytest tutorial<\/a> at <a href=\"https:\/\/2024.pycon.de\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">PyCon DE 2024<\/a> and I learned a couple of really neat tricks to improve parametrised tests.<\/p>\n<p>Let's take a look at them!<\/p>\n<h3 id=\"stacking-the-parametrize-mark\">Stacking the <code>parametrize<\/code> mark<a href=\"#stacking-the-parametrize-mark\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>One quick tip is that you can stack <code>parametrize<\/code> to run all permutations of different parameters.<\/p>\n<p>For example, if <code>calc<\/code> is a function that does basic arithmetic operations, the test below will test 9 different additions:<\/p>\n<pre><code class=\"language-py\">import pytest\n\n@pytest.mark.parametrize(\"a\", [-3, 0, 5])\n@pytest.mark.parametrize(\"b\", [-8, 0, 42])\ndef test_calc_add(a, b):\n    assert calc(a, b, \"+\") == a + b<\/code><\/pre>\n<p>Running this test, you get the following output:<\/p>\n<pre><code>test_calc.py::test_calc_add[-8--3] PASSED     [ 11%]\ntest_calc.py::test_calc_add[-8-0] PASSED      [ 22%]\ntest_calc.py::test_calc_add[-8-5] PASSED      [ 33%]\ntest_calc.py::test_calc_add[0--3] PASSED      [ 44%]\ntest_calc.py::test_calc_add[0-0] PASSED       [ 55%]\ntest_calc.py::test_calc_add[0-5] PASSED       [ 66%]\ntest_calc.py::test_calc_add[42--3] PASSED     [ 77%]\ntest_calc.py::test_calc_add[42-0] PASSED      [ 88%]\ntest_calc.py::test_calc_add[42-5] PASSED      [100%]<\/code><\/pre>\n<p>With this pattern you cannot specify a test output for each single test, so this will only work if you have a different way of computing the result or if the expected result is always the same.<\/p>\n<p>For tests where you must specify the expected result but you also want to test all permutations of certain parameters, you can use the REPL and <code>itertools.product<\/code> to programmatically generate all the tests instead of having to write them down by hand.<\/p>\n<h3 id=\"parametrising-with-named-tuples\">Parametrising with named tuples<a href=\"#parametrising-with-named-tuples\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>You can add a lot of flexibility and readability in your parametrised tests if you use named tuples<sup id=\"fnref1:1\"><a href=\"#fn:1\" class=\"footnote-ref\">1<\/a><\/sup>.\nInstead of listing tuples with plenty of different values, we can create a named tuple to wrap around those tuples, which then lets us use named parameters <em>and<\/em> default arguments in our parametrisation cases!<\/p>\n<p>As an example, consider a test that's parametrised in the conventional way:<\/p>\n<pre><code class=\"language-py\">import pytest\n\n@pytest.mark.parametrize(\n    [\"a\", \"b\", \"op\", \"result\", \"flag1\", \"flag2\"],\n    [\n        (10, 15, \"+\", 25, True, False),\n        (10, 15, \"-\", -5, True, False),\n        (3, 18, \"*\", 54, False, False),\n        (18, 3, \"\/\", 6, True, False),\n        (5, 0, \"\/\", None, True, True),\n    ]\n)\ndef test_something(a, b, op, result, flag1, flag2):\n    # do stuff with a, b, op, ...\n    ...<\/code><\/pre>\n<p>If you create a named tuple, you could use the names of the parameters to help disambiguate the two flags, for example, and you could also add default values:<\/p>\n<pre><code class=\"language-py\">from typing import NamedTuple\nimport pytest\n\nclass CaseParam(NamedTuple):\n    a: int\n    b: int\n    op: str\n    result: int\n    flag1: bool = True\n    flag2: bool = False\n\n@pytest.mark.parametrize(\n    [\"a\", \"b\", \"op\", \"result\", \"flag1\", \"flag2\"],\n    [\n        CaseParam(10, 15, \"+\", 25),\n        CaseParam(10, 15, \"-\", -5),\n        CaseParam(3, 18, \"*\", 54, flag1=False),\n        CaseParam(18, 3, \"\/\", 6),\n        CaseParam(5, 0, \"\/\", None, flag2=True),\n    ]\n)\ndef test_something(a, b, op, result, flag1, flag2):\n    # do stuff with a, b, op, ...\n    ...<\/code><\/pre>\n<p>This does add more code to your tests, so it's not really reasonable to do it for every single parametrisation you'll create, but it might come in handy for more complex parametrisations.\nI really liked this...<\/p>","summary":"Today I learned how to use named tuples to improve readability and flexibility of test parametrisations in pytest.","date_modified":"2025-09-06T19:56:10+02:00","tags":["modules","productivity","programming","pytest","python","testing"],"image":"\/user\/pages\/02.blog\/04.til\/095.better-test-parametrisation-in-pytest\/thumbnail.webp"},{"title":"TIL #094 \u2013 pytest.raises: parameter match","date_published":"2024-04-22T16:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/pytest.raises-parameter-match","url":"https:\/\/mathspp.com\/blog\/til\/pytest.raises-parameter-match","content_html":"<p>Today I learned about the parameter <code>match<\/code> used in <code>pytest.raises<\/code>.<\/p>\n\n<h2 id=\"pytest-raises-parameter-match\"><code>pytest.raises<\/code>: parameter <code>match<\/code><a href=\"#pytest-raises-parameter-match\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Today I attended a <a href=\"https:\/\/pretalx.com\/pyconde-pydata-2024\/talk\/DSFWRC\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">pytest tutorial<\/a> at <a href=\"https:\/\/2024.pycon.de\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">PyCon DE 2024<\/a> and very early in the tutorial I learned about the parameter <code>match<\/code> that you can use with <code>pytest.raises<\/code>.<\/p>\n<p>The parameter <code>match<\/code> accepts a regex pattern that is tested against the error message and your test only passes if the error message matches the regex.<\/p>\n<p>The initial example given was this:<\/p>\n<pre><code class=\"language-py\">def parse_pos_number(s: str) -&gt; int:\n    n = int(s)\n    if n &lt; 0:\n        raise ValueError(\"No negativity allowed!\")\n    return n<\/code><\/pre>\n<p>This function raises a <code>ValueError<\/code> if you pass it a negative value but it will also raise a (different) <code>ValueError<\/code> if you pass it a string that doesn't look like an integer:<\/p>\n<pre><code class=\"language-py\">parse_pos_number(\"-1\")  # ValueError: No negativity allowed!\nparse_pos_number(\"a\")   # ValueError: invalid literal for int() with base 10: 'a'<\/code><\/pre>\n<p>So, when writing a test to make sure that <code>parse_pos_number<\/code> fails when giving it a negative number, we should also ensure that the <code>ValueError<\/code> is \u201cthe correct one\u201d.\nThe test would look like this:<\/p>\n<pre><code class=\"language-py\">import pytest\n\ndef test_with_negative_number():\n    with pytest.raises(ValueError, match=\"No negativity allowed!\"):\n        parse_pos_number(\"-1\")<\/code><\/pre>\n<p>The trainer also put forward that this parameter <code>match<\/code> can be quite useful if you have a (custom) error that is raised in multiple situations.\nAdding <code>match<\/code> to your tests will also test your error messages and it acts as a \u201cdocumentation\u201d test.<\/p>","summary":"Today I learned about the parameter `match` used in `pytest.raises`.","date_modified":"2025-07-23T16:49:02+02:00","tags":["modules","programming","pytest","python","testing"],"image":"\/user\/pages\/02.blog\/04.til\/094.pytest.raises-parameter-match\/thumbnail.webp"},{"title":"TIL #090 \u2013 patching module globals with pytest","date_published":"2024-01-25T09:30:00+01:00","id":"https:\/\/mathspp.com\/blog\/til\/patching-module-globals-with-pytest","url":"https:\/\/mathspp.com\/blog\/til\/patching-module-globals-with-pytest","content_html":"<p>Yesterday I spent the whole day tryint to patch a module global.\nThis is what I ended up with.<\/p>\n\n<h2 id=\"patching-module-globals-with-pytest\">Patching module globals with <code>pytest<\/code><a href=\"#patching-module-globals-with-pytest\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Suppose you have a small project that has an April Fool's joke set up:<\/p>\n<pre><code class=\"language-py\">## constants.py\n\nAPRIL_FOOLS = False<\/code><\/pre>\n<pre><code class=\"language-py\">## useful_code.py\n\nfrom constants import APRIL_FOOLS\n\ndef add(a, b):\n    if APRIL_FOOLS:\n        result = a - b\n    else:\n        result = a + b\n    return result<\/code><\/pre>\n<p>Now, suppose you want to test your April Fool's joke with <code>pytest<\/code>.\nOne thing I found online was that you could use the fixture <code>monkeypatch<\/code> and its method <code>setattr<\/code>, something like this:<\/p>\n<pre><code class=\"language-py\">## test_useful_code.py\n\nimport pytest\n\nimport constants\nimport useful_code\n\ndef test_add_on_april_fools(monkeypatch):\n    monkeypatch.setattr(constants, \"APRIL_FOOLS\", True)\n    assert useful_code.add(10, 5) == 5<\/code><\/pre>\n<p>(I'm sparing you from hearing about all of the embarrissingly dumb things I tried before getting to this point!)<\/p>\n<p>If you run this test with <code>pytest test_useful_code.py<\/code> you get a failure:<\/p>\n<pre><code>FAILED test_useful_code.py::test_add_on_april_fools - assert 15 == 5<\/code><\/pre>\n<p>What's happening, then?\nTake a moment to think about it...<\/p>\n<p>What's happening is that when I import <code>useful_code<\/code> into the testing file, that module will then run the line <code>from constants import APRIL_FOOLS<\/code>, which sets the variable <code>APRIL_FOOLS<\/code> inside the namespace of the module <code>useful_code<\/code>, which is <em>separate<\/em> from the namespace of the module <code>constants<\/code>!<\/p>\n<p>After banging my head against the wall for a while, I realised I could tweak my code to work with this testing approach!\nAll I had to do was use <code>constants.APRIL_FOOLS<\/code> instead of using <code>APRIL_FOOLS<\/code> directly:<\/p>\n<pre><code class=\"language-py\">## useful_code.py\n\nimport constants\n\ndef add(a, b):\n    if constants.APRIL_FOOLS:\n        result = a - b\n    else:\n        result = a + b\n    return result<\/code><\/pre>\n<p>Now, if you run your test it will pass and the mocking of the variable will have succeeded!<\/p>\n<p>The reason this works is that now we're accessing <code>APRIL_FOOLS<\/code> via the <code>constants<\/code> namespace, so when we patch the value of <code>APRIL_FOOLS<\/code> in <code>constants<\/code>, that patched value will be visible when the constant is used elsewhere.<\/p>\n<p>You could also patch <code>APRIL_FOOLS<\/code> directly in the module <code>useful_code<\/code>, but if you have a constant that is used in many different modules, it is much easier (and better) to patch it <em>once<\/em> where it is defined versus patching it many times wherever it is imported.<\/p>\n<p>I'm not claiming this is <em>the best solution<\/em> to this problem but it's certainly <em>a solution that works<\/em>.\nIf you have better ideas that have more or less the same complexity, let me know!<\/p>\n<p>For reference, this is a simplification of a \u201creal\u201d issue I had when trying to add tests to <a href=\"https:\/\/github.com\/Textualize\/textual\/pull\/4062\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this Textual PR of mine<\/a>.<\/p>","summary":"Today I learned how to patch module globals with pytest.","date_modified":"2025-07-23T16:49:02+02:00","tags":["programming","pytest","python","testing"],"image":"\/user\/pages\/02.blog\/04.til\/090.patching-module-globals-with-pytest\/thumbnail.webp"},{"title":"TIL #063 \u2013 skip tests on Microsoft Windows","date_published":"2023-06-12T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/skip-tests-on-microsoft-windows","url":"https:\/\/mathspp.com\/blog\/til\/skip-tests-on-microsoft-windows","content_html":"<p>Today I learned how to skip tests on Microsoft Windows in <code>pytest<\/code>.<\/p>\n\n<h2 id=\"pytest-mark-skip\"><code>pytest.mark.skip<\/code><a href=\"#pytest-mark-skip\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In <code>pytest<\/code>, you can skip a specific test by using the decorator <code>pytest.mark.skip<\/code>.<\/p>\n<p>For example, the test below will never run:<\/p>\n<pre><code class=\"language-py\">import pytest\n\n@pytest.mark.skip\ndef test_yeah():\n    assert False<\/code><\/pre>\n<p>Instead of running the test, <code>pytest<\/code> shows it was skipped:<\/p>\n<p><img src=\"\/blog\/til\/skip-tests-on-microsoft-windows\/.\/_skip.webp\" alt=\"\"><\/p>\n<p>However, the decorator <code>pytest.mark.skip<\/code> will <em>always<\/em> skip your test.\nSometimes, you only want to skip under certain circumstances.<\/p>\n<h2 id=\"how-to-conditionally-skip-a-test-in-pytest\">How to conditionally skip a test in <code>pytest<\/code>?<a href=\"#how-to-conditionally-skip-a-test-in-pytest\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>If you want to skip a <code>pytest<\/code> test conditionally, you need to use the decorator <code>pytest.mark.skipif<\/code>.<\/p>\n<p>For example, the test below will only run if the current Python version is 3.7 or higher:<\/p>\n<pre><code class=\"language-py\">import pytest\nimport sys\n\n@pytest.mark.skipif(sys.version_info &lt; (3, 7))\ndef test_foo():\n    assert True<\/code><\/pre>\n<p>The decorators <code>skip<\/code> and <code>skipif<\/code> also accept a keyword argument <code>reason<\/code> that you can use to give more information as to why you are skipping a given test:<\/p>\n<pre><code class=\"language-py\">import pytest\nimport sys\n\n@pytest.mark.skip(reason=\"We skip because this always fails.\")\ndef test_yeah():\n    assert False\n\n@pytest.mark.skipif(sys.version_info &lt; (3, 7), reason=\"Only works on 3.7+.\")\ndef test_foo():\n    assert True<\/code><\/pre>\n<p>We can do a similar thing if we only want a test to run under Windows.\nOr if we do <em>not<\/em> want a test to run under Windows.<\/p>\n<h2 id=\"how-to-skip-a-test-on-microsoft-windows\">How to skip a test on Microsoft Windows<a href=\"#how-to-skip-a-test-on-microsoft-windows\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>If you want to skip a test if you are running on Windows, you would mark it with <code>skipif<\/code> and then you check if the platform is Windows.<\/p>\n<p>For example, the test below will not run if the current operating system is Microsoft Windows:<\/p>\n<pre><code class=\"language-py\">import pytest\nimport sys\n\n@pytest.mark.skipif(\n    sys.platform ==\"win32\", reason=\"Windows doesn't have what it takes.\"\n)\ndef test_something_not_on_windows():\n    assert ...<\/code><\/pre>\n<h2 id=\"how-to-skip-a-whole-test-file\">How to skip a whole test file<a href=\"#how-to-skip-a-whole-test-file\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>If you want to skip a whole test file, you can assign the result of <code>skipif<\/code> to the global variable <code>pytestmark<\/code>.\nFor example, the file below would only run its tests if you were running on Windows and specifically with Python 3.10:<\/p>\n<pre><code class=\"language-py\">import pytest\nimport sys\n\npytestmark = pytest.mark.skipif(\n    sys.platform == \"win32\" and sys.version_info == (3, 10)\n)\n\ndef test_one():\n    assert 1 == 1\n\ndef test_two():\n    assert int(\"2\") == 2\n\ndef test_three():\n    assert str(3) == \"3\"<\/code><\/pre>\n<h2 id=\"why-would-you-skip-some-tests\">Why would you skip some tests?<a href=\"#why-would-you-skip-some-tests\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>There are several plausible reasons why you'd want to skip a couple of tests in &ldquo;real life&rdquo;.<\/p>\n<p>For example, you might want to skip some tests in certain versions of Python if you are trying to use functionality that was introduced in a later version of Python.\nThis could also apply to specific versions of certain dependencies.<\/p>\n<p>Another example, and the reason that led to me learning this, was when working on <a href=\"https:\/\/github.com\/textualize\/textual\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Textual<\/a>: I needed to skip a specific test if I was <em>not<\/em> running under Microsoft Windows because I had to implement a function that would only be called under Windows and that would use Windows-specific APIs...\nSo, even if I wanted to run the test on other operating systems, the test could never pass because those operating systems...<\/p>","summary":"Today I learned how to skip tests on Microsoft Windows in `pytest`.","date_modified":"2025-07-23T16:49:02+02:00","tags":["modules","programming","pytest","python"],"image":"\/user\/pages\/02.blog\/04.til\/063.skip-tests-on-microsoft-windows\/thumbnail.webp"}]}
