<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Fabio Ramalho]]></title><description><![CDATA[Fabio Ramalho]]></description><link>https://dev.fabioramalho.me</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 18:16:14 GMT</lastBuildDate><atom:link href="https://dev.fabioramalho.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[@pytest.mark.parametrize: Enhancing clarity with "wrapped" parametrized arguments]]></title><description><![CDATA[One of the Pytest features I like and use most is @pytest.mark.parametrize. Below is an example of how to use it (from Pytest documentation):
import pytest


@pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8), ("2+4", 6), ("6*9", 42)
])...]]></description><link>https://dev.fabioramalho.me/pytestmarkparametrize-enhancing-clarity-with-wrapped-parametrized-arguments</link><guid isPermaLink="true">https://dev.fabioramalho.me/pytestmarkparametrize-enhancing-clarity-with-wrapped-parametrized-arguments</guid><category><![CDATA[Python]]></category><category><![CDATA[pytest]]></category><dc:creator><![CDATA[Fabio Ramalho]]></dc:creator><pubDate>Sat, 01 Jul 2023 21:03:17 GMT</pubDate><content:encoded><![CDATA[<p>One of the Pytest features I like and use most is <a target="_blank" href="https://docs.pytest.org/en/7.3.x/how-to/parametrize.html"><code>@pytest.mark.parametrize</code></a>. Below is an example of how to use it (from <a target="_blank" href="https://docs.pytest.org/en/7.3.x/how-to/parametrize.html#pytest-mark-parametrize-parametrizing-test-functions">Pytest documentation</a>):</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pytest


<span class="hljs-meta">@pytest.mark.parametrize("test_input,expected", [</span>
    (<span class="hljs-string">"3+5"</span>, <span class="hljs-number">8</span>), (<span class="hljs-string">"2+4"</span>, <span class="hljs-number">6</span>), (<span class="hljs-string">"6*9"</span>, <span class="hljs-number">42</span>)
])
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_eval</span>(<span class="hljs-params">test_input, expected</span>):</span>
    <span class="hljs-keyword">assert</span> eval(test_input) == expected
</code></pre>
<h3 id="heading-scenario">Scenario</h3>
<p>For tests where there are one or two parametrized arguments only, the names and values for the arguments are easily readable. However, the complexity can increase when there are several parametrized arguments and, even more when <a target="_blank" href="https://docs.pytest.org/en/6.2.x/fixture.html#back-to-fixtures">fixtures</a> are passed to the test function as well. In such cases, it is not immediate to map the value to the argument for a given input when reading the code. In the example below we can notice that the test signature is longer (as expected) and there is no clear distinction between the parametrized arguments and the fixtures passed in.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pytest

<span class="hljs-meta">@pytest.fixture()</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">dummy</span>():</span>
    <span class="hljs-comment"># Dummy fixture</span>
    <span class="hljs-keyword">return</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">eval_math_operation</span>(<span class="hljs-params">x: int, operator: str, y: int</span>) -&gt; int:</span>
    <span class="hljs-comment"># Dummy function just for illustration purposes</span>
    <span class="hljs-keyword">return</span> eval(<span class="hljs-string">f"<span class="hljs-subst">{x}</span> <span class="hljs-subst">{operator}</span> <span class="hljs-subst">{y}</span>"</span>)


<span class="hljs-meta">@pytest.mark.parametrize("x, operator, y, expected", (</span>
        (<span class="hljs-number">1</span>, <span class="hljs-string">"+"</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>),
        (<span class="hljs-number">1</span>, <span class="hljs-string">"-"</span>, <span class="hljs-number">2</span>, <span class="hljs-number">-1</span>),
        (<span class="hljs-number">1</span>, <span class="hljs-string">"*"</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>),
        (<span class="hljs-number">1</span>, <span class="hljs-string">"/"</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0.5</span>),
))
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_eval_math_operation</span>(<span class="hljs-params">x, operator, y, expected, dummy</span>):</span>
    <span class="hljs-keyword">assert</span> eval_math_operation(x, operator, y) == expected
</code></pre>
<h3 id="heading-an-alternative-approach">An alternative approach</h3>
<p>To enhance clarity on the inputs of the tests, I usually prefer to wrap each set of parametrized arguments into a dictionary so "what would be" the parametrized arguments becomes a single one.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pytest 

<span class="hljs-meta">@pytest.fixture()</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">dummy</span>():</span>
    <span class="hljs-comment"># Dummy fixture</span>
    <span class="hljs-keyword">return</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">eval_math_operation</span>(<span class="hljs-params">x: int, operator: str, y: int</span>) -&gt; int:</span>
    <span class="hljs-comment"># Dummy function just for illustration purposes</span>
    <span class="hljs-keyword">return</span> eval(<span class="hljs-string">f"<span class="hljs-subst">{x}</span> <span class="hljs-subst">{operator}</span> <span class="hljs-subst">{y}</span>"</span>)

<span class="hljs-meta">@pytest.mark.parametrize("test_case", (</span>
        dict(x=<span class="hljs-number">1</span>, operator=<span class="hljs-string">"+"</span>, y=<span class="hljs-number">2</span>, expected=<span class="hljs-number">3</span>),
        dict(x=<span class="hljs-number">1</span>, operator=<span class="hljs-string">"-"</span>, y=<span class="hljs-number">2</span>, expected=<span class="hljs-number">-1</span>),
        dict(x=<span class="hljs-number">1</span>, operator=<span class="hljs-string">"*"</span>, y=<span class="hljs-number">2</span>, expected=<span class="hljs-number">2</span>),
        dict(x=<span class="hljs-number">1</span>, operator=<span class="hljs-string">"/"</span>, y=<span class="hljs-number">2</span>, expected=<span class="hljs-number">0.5</span>),
))
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_eval_math_operation</span>(<span class="hljs-params">test_case, dummy</span>):</span>
    <span class="hljs-keyword">assert</span> eval_math_operation(
        x=test_case[<span class="hljs-string">"x"</span>],
        operator=test_case[<span class="hljs-string">"operator"</span>],
        y=test_case[<span class="hljs-string">"y"</span>]
    ) == test_case[<span class="hljs-string">"expected"</span>]
</code></pre>
<p>That way, it is easier to understand not only the arguments in each test case but also the test signature, wherein it is now clear the distinction between the single test's parametrized argument and any additional fixtures. The test runner doesn't complain and the others reading the code may thank you! 😄</p>
]]></content:encoded></item><item><title><![CDATA["Hello... World?"]]></title><description><![CDATA[Hi everyone and welcome to what will be my tech-knowledge garden (at least, that's my goal with this blog). I have decided to embark on this new adventure of blogging to document and share my knowledge and experiences in the world of software develop...]]></description><link>https://dev.fabioramalho.me/hello-world</link><guid isPermaLink="true">https://dev.fabioramalho.me/hello-world</guid><dc:creator><![CDATA[Fabio Ramalho]]></dc:creator><pubDate>Fri, 02 Jun 2023 22:04:36 GMT</pubDate><content:encoded><![CDATA[<p>Hi everyone and welcome to what will be my tech-knowledge garden (at least, that's my goal with this blog). I have decided to embark on this new adventure of blogging to document and share my knowledge and experiences in the world of software development.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1685778927621/6f2ce136-5b78-44cd-94ef-cabc44923dea.png" alt="Image generated by OpenAI’s DALL·E 2 on 2nd June 2023 with the prompt &quot;Genesis of the knowledge book, coming from the roots of a tree in an idyllic garden. psychedelic style&quot;" class="image--center mx-auto" /></p>
<center><em>Image generated by OpenAI’s DALL·E 2 on 2nd June 2023 with the prompt "Genesis of the knowledge book, coming from the roots of a tree in an idyllic garden. Psychedelic style"</em></center>

<p>The posts might include ideas, TILs (Today I Learned), tips and tricks, or documentation of steps and procedures, among others, usually in the context of programming. Although, in most cases, they might cover contents that may already exist elsewhere, here I will share them from my perspective, with my opinion, using my own words, and always explicitly citing the sources. On the other hand, they can also encompass insights that I have personally developed and find valuable enough to share with others.</p>
<p>Just as software development is an iterative and ever-evolving process, so too is the craft of writing. I will challenge myself to overcome the inclination to endlessly refine and perfect my posts, instead prioritizing the act of getting them written and published, only then making tweaks if needed according to incoming feedback.</p>
<p><strong>Growing Beyond Code</strong></p>
<p>In addition to the <em>techy</em> context, with this blog, I also pretend to improve my (English) writing skills constituting an exercise to refine my grammar and syntax as well as find new ways to express my ideas.</p>
]]></content:encoded></item></channel></rss>