<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Charles</title>
    <description>The latest articles on DEV Community by Charles (@selrahcd).</description>
    <link>https://dev.to/selrahcd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F456162%2F1b47f382-73b6-4e41-b9fe-602978df3385.jpeg</url>
      <title>DEV Community: Charles</title>
      <link>https://dev.to/selrahcd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/selrahcd"/>
    <language>en</language>
    <item>
      <title>Approval testing: 3 technics to deal with randomness</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Thu, 19 Jan 2023 14:33:26 +0000</pubDate>
      <link>https://dev.to/selrahcd/approval-testing-3-technics-to-deal-with-randomness-6lp</link>
      <guid>https://dev.to/selrahcd/approval-testing-3-technics-to-deal-with-randomness-6lp</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was previously posted on &lt;a href="https://blog.charlesdesneuf.com/articles/approval-testing-3-technics-to-deal-with-randomness/?utm_medium=social&amp;amp;utm_source=devto&amp;amp;utm_campaign=dev_to_article" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When dealing with legacy code, randomness is not something you enjoy meeting.&lt;/p&gt;

&lt;p&gt;Creating a test harness on top of a system with random results can be pretty challenging.&lt;/p&gt;

&lt;p&gt;Obviously, you’d like your tests to be deterministic and to always give you the same result, provided you didn’t change anything in the system.&lt;/p&gt;

&lt;p&gt;Let’s see three ideas that can help you deal with the randomness in the system. The first two technics are based on the idea of removing the random part of the system during tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Block the random generator
&lt;/h2&gt;

&lt;p&gt;The first solution I wanted to offer in this article is to ensure that the random generator always returns the same results when called. The answer here is to seed the generator with a value you control, to make the generator work in a deterministic manner.&lt;/p&gt;

&lt;p&gt;For instance, in PHP, you can call the &lt;code&gt;mt_rand&lt;/code&gt; function. Later, any call to the &lt;code&gt;rand&lt;/code&gt; function will return the same random numbers in the same order.&lt;/p&gt;

&lt;p&gt;This is a fast way to turn the non-deterministic system into something that always gives the same results.&lt;/p&gt;

&lt;p&gt;Unfortunately, this solution, while being one of the quickest ways to get the job done, only works in some situations. First, not all languages allow seeding the random number generator. If you can’t, you can’t and need another solution.&lt;/p&gt;

&lt;p&gt;Another caveat of this solution is that if you modify the structure of your code and the order of calls to a random method is changed; you’ll get results in the same order but not in the same logical space. For instance, let’s take two calls to &lt;code&gt;rand&lt;/code&gt; and assign the result of the first call to variable A and the second call to variable B. After seeding the random number generator, A and B are always set to the same value, say 34 and 1879. During a refactoring, if we decide to invert the order assignation, we have a problem. The code now assigns values to B before A; A is now 1879, and B is 39. You can play with this idea &lt;a href="https://onlinephp.io?s=bZDBTsMwDIbPVMo7mKrSutNo6WAFKjTQJA67wXGXrHXXSmlSOenGhDjyFjwdT0KaFiYkpBxi-_f_2b67b6uWecwrO5mbWkkgLgvVrHHH8-OjKjCcwhvzzmYzeKEj1HKPZGq5A1MhmIOCUgmhDn1G1BK1lQYcMmcTTm_7cPsntI_QdCTBX0KtwaptDR7cf-tbyXs_D_NGYq6aBuWItJqewjztDKPe0SmfkLB3UB0Bb1tSey7AoDbMC_C1xdxgYceYOOQinc-T6zSOT-Q4SqLkcnFxlU6sZcBz01mD7J9rOGJdhj-a8wx-CcOpMK8U-CsiRRu5Gks3J9VGLl2rTQ0e49IoNMLQ_PX58cwbBELdCeODg34D&amp;amp;v=8.2.1" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What can we do when seeding the random number generator is impossible, or we might want to change the order of the calls at some point?&lt;/p&gt;

&lt;h2&gt;
  
  
  Control the randomness
&lt;/h2&gt;

&lt;p&gt;The other alternative is to take back control of the values generation. As often, adding a layer of abstraction is one of the solutions available in our toolbox. Here we want to break the direct dependency to the random value generator and swap it with a dependency we can manipulate.&lt;/p&gt;

&lt;p&gt;In more concrete terms, instead of directly calling a function from the language, we encapsulate it, create a stub we can manipulate, and find a way to substitute the original implementation with our double.&lt;/p&gt;

&lt;p&gt;The substitution technics available greatly vary depending on the programming language you’re using and the code’s state. If you’re lucky enough to be able to inject dependencies at construction, this is an easy task. If you’re not, some patterns from &lt;em&gt;Working Effectively With Legacy Code&lt;/em&gt; by Michael Feathers can prove helpful.&lt;/p&gt;

&lt;p&gt;This solution is available in every language. The only requirement is to feel comfortable messing around with code while not having tests to be able to take control back.&lt;/p&gt;

&lt;p&gt;Once you have control, you can decide the values generated.&lt;/p&gt;

&lt;p&gt;That solution allows us to solve the ordering issue mentioned before. If you invert the order of calls in the code, you can change the configuration of your stub to change the order and keep the tests passing.&lt;/p&gt;

&lt;p&gt;Modifying the stub after tests are created needs to be done carefully. If you want greater confidence and want to avoid touching the tests, you have another alternative. Instead of making one abstraction for every call to the random generator, you can create one for each call. Taking back the example from the first part, you can introduce an abstraction for generating A and an abstraction for generating B. Having two implementations gives you more granular control, and you can create two stubs. When you invert the call order, the code still calls the right abstractions and the same stubs and obtains the same final result.&lt;/p&gt;

&lt;p&gt;Touching an existing code base to introduce indirections to control randomly generated value is not always straightforward nor necessary. Sometimes we don’t care about the generated value, and we can be totally fine with keeping the randomness as long as we manage to keep our tests deterministic. And this is the point of the third idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hide the randomness
&lt;/h2&gt;

&lt;p&gt;Sometimes the random value is not really important for the result. If we don’t care about it, we can remove it from what is asserted in the test.&lt;/p&gt;

&lt;p&gt;The trick here is that you don’t need to make assertions based on the direct outputs of the system under test. Instead, you can get them and transform them to keep only the information you need to be confident enough that you’re not breaking anything.&lt;/p&gt;

&lt;p&gt;When doing approval testing, it is common to use a printer, a function or a class that will transform the outputs to make them look easy to understand. If a piece of information is not relevant, the printer’s role is to remove it and create a clean output. You can then use that clean output in the assertion.&lt;/p&gt;

&lt;p&gt;What could be simpler than removing what you don’t care about?&lt;/p&gt;

&lt;p&gt;Sometimes you don’t care about the actual value, but you want to ensure that a value is here. Instead of removing the random part, you can replace it with something else. Say you don’t care about the value of a UUID but want to be sure that it is displayed. Using a regular expression, you can replace all UUIDs with something else, like a &lt;code&gt;UUID&lt;/code&gt; string.&lt;/p&gt;

&lt;p&gt;Another common use case is to detect that a value is repeated in several places in the output.&lt;/p&gt;

&lt;p&gt;Let’s continue with the previous example. You still don’t care about the value of the UUID, but you want to assert that the UUID used in a link to access a product is the product’s UUID, not some other one.&lt;/p&gt;

&lt;p&gt;Here the printer has to be more clever.&lt;/p&gt;

&lt;p&gt;When a UUID is detected using a regex, the scrubber generates a new string, usually made from a base string and an increment (&lt;code&gt;UUID_1&lt;/code&gt;). Then it replaces all the subsequent occurrences of that UUID with the generated string, increments the counter and repeats for each UUID found in the output. That way, even if you can’t predetermine the result of the system, you can turn it into something deterministic that you can use as your golden master.&lt;/p&gt;

&lt;p&gt;The good thing about this solution is that it doesn’t require touching the legacy system. You don’t need to worry about breaking something while creating the tests. This is why it is a very convenient and relatively rapid method to build confidence. Also, you might be very lucky and work with a language where approval testing tools come with scrubbers doing part of the cleaning work for you.&lt;/p&gt;

&lt;p&gt;Discovering a system using randomness and needing to create a test harness doesn’t have to be scary or take an awful lot of time. With the three ideas exposed in this article, you should be able to attack that piece of legacy code you avoided refactoring for a while.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Comment tester une méthode privée ?</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Wed, 21 Sep 2022 11:16:10 +0000</pubDate>
      <link>https://dev.to/selrahcd/comment-tester-une-methode-privee--5130</link>
      <guid>https://dev.to/selrahcd/comment-tester-une-methode-privee--5130</guid>
      <description>&lt;p&gt;&lt;em&gt;Cet article a été posté précédemment sur &lt;a href="https://blog.charlesdesneuf.com/articles/comment-tester-une-methode-privee/?utm_medium=social&amp;amp;utm_source=devto&amp;amp;utm_campaign=devto_article"&gt;mon blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dans cet article quand j’utilise le terme "méthode privée" cela correspond aux méthodes qui ne sont pas accessibles depuis l’interface publique d’une classe. En PHP, par exemple, il peut s’agir de méthodes &lt;code&gt;private&lt;/code&gt; ou &lt;code&gt;protected&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On ne la teste pas. Ça, c’est la réponse courte. La réponse longue demande un peu plus d’effort.&lt;/p&gt;

&lt;p&gt;Commençons par le commencement.&lt;/p&gt;

&lt;p&gt;La question originale est trompeuse. En réalité &lt;strong&gt;on ne cherche pas à tester une méthode&lt;/strong&gt;, quelle soit &lt;code&gt;private&lt;/code&gt;, &lt;code&gt;protected&lt;/code&gt; ou &lt;code&gt;public&lt;/code&gt;, &lt;strong&gt;mais un comportement&lt;/strong&gt;. On veut savoir ce que fait notre logiciel, pas comment il le fait, et donc la manière dont on implémente ce comportement nous importe assez peu.&lt;/p&gt;

&lt;p&gt;Évidemment, on va quand même retrouver une méthode publique comme point d’entrée du comportement, mais la méthode privée, elle, est un &lt;strong&gt;détail d’implémentation&lt;/strong&gt;. Le comportement qui nous intéresse pourrait tout aussi bien être servi par une méthode publique qui contient l’ensemble du code nécessaire, ou une méthode publique qui délègue une partie du travail à une ou plusieurs méthodes privées, ou même encore à une ou plusieurs autres méthodes publiques d’autres classes. En somme, &lt;strong&gt;l’existence ou non d’une méthode privée ne nous intéresse pas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pour tester le comportement, on va donc se placer à l’endroit où l’on peut le déclencher et vérifier son bon déroulement, c’est-à-dire au niveau de la méthode publique. Au passage cela va "tester la méthode privée", ou plus précisément "exercer le code contenu dans la méthode privée". Encore une fois, on ne veut pas tester une méthode privée mais un comportement qui s’appuie sur une méthode privée. On peut dire que l'&lt;strong&gt;on "teste" la méthode privée via une méthode publique.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Oui, mais cette méthode privée est complexe
&lt;/h2&gt;

&lt;p&gt;Ceci étant dit, il se peut que le code présent dans la méthode privée soit assez complexe pour que l’on ait envie de pouvoir exercer ce bout de code sans avoir à passer par la méthode publique. On veut ainsi éviter de devoir faire une mise en place de test complexe, d’avoir à zigzaguer au milieu du reste du code pour pouvoir se placer dans un cas particulier du comportement qui nous intéresse.&lt;/p&gt;

&lt;p&gt;Une solution couramment proposée est d’essayer de contourner le problème en rendant la méthode privée accessible. Ce qui peut se faire en utilisant le système de réflexion du langage. L’avantage de cette solution est que l’on n’a pas à toucher au code. En revanche on ajoute de la complexité à la mise en place de notre test et l’on augmente le couplage entre les tests et le code. Cela peut alors nuire à un potentiel futur refactoring, puisque les tests ont alors une connaissance assez fine de l’implémentation.&lt;/p&gt;

&lt;p&gt;Une autre solution, bien meilleure selon moi, est d’&lt;strong&gt;écouter les tests&lt;/strong&gt;. Comme très souvent, &lt;strong&gt;quand quelque chose est compliqué à tester ce ne sont pas les tests le problème mais la conception du code&lt;/strong&gt;.&lt;br&gt;
En nous montrant qu’un bout du comportement est complexe, si complexe que nous avons envie de pouvoir nous assurer de son bon fonctionnement séparément du reste &lt;strong&gt;les tests nous indiquent qu’il nous manque un concept&lt;/strong&gt;, qu’&lt;strong&gt;il manque un collaborateur&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Il faut alors prendre le temps de trouver quel est ce concept, de le définir, de le nommer. On peut ensuite &lt;strong&gt;introduire ce nouveau concept dans notre code à l’aide d’une nouvelle classe et y transférer la méthode privée, que l’on rend publique au passage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cela nécessite, certes, de modifier le code, mais permet de &lt;strong&gt;faire naitre un vocabulaire plus riche pour discuter du problème que l’on cherche à résoudre&lt;/strong&gt;. On est capable de documenter cette partie du comportement par elle-même au travers des tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On n’a pas non plus besoin d’utiliser d’astuces qui complexifient les tests, un simple appel à la nouvelle méthode publique suffit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On a réussi à transformer notre problème. Puisqu’il n’y a plus de méthode privée on n’a plus besoin d’essayer de tester de méthode privée.&lt;/p&gt;

&lt;p&gt;Voilà pourquoi la réponse longue à la question "Comment tester une méthode privée ?" est aussi "On ne la teste pas".&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Envie d'en apprendre davantage sur les tests ?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;J’ai créé une formation vidéo qui aide les développeuses et développeurs à &lt;a href="https://formation.charlesdesneuf.com/9e5b4913-ead7-4c2f-82c2-ac9a08b9a454"&gt;améliorer leurs tests automatisés&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dans cette formation je partage les idées et techniques qui permettent de rendre des tests lents, qui cassent à chaque modification du code et sont incompréhensibles en des tests avec lesquels on a plaisir à travailler.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>french</category>
      <category>testing</category>
    </item>
    <item>
      <title>Generating dates and UUIDs easily in PhpStorm</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Fri, 13 Aug 2021 10:22:53 +0000</pubDate>
      <link>https://dev.to/selrahcd/generating-dates-and-uuids-easily-in-phpstorm-j3n</link>
      <guid>https://dev.to/selrahcd/generating-dates-and-uuids-easily-in-phpstorm-j3n</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was previously posted on &lt;a href="https://blog.charlesdesneuf.com?utm_medium=social&amp;amp;utm_source=dev_to&amp;amp;utm_campaign=article-generating-dates"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Legacy codebases tend to lack tests. One way to introduce some safety net before messing around with the code is to add characterization tests.&lt;br&gt;
In this kind of test, we feed some input to the system under test and look at the outputs, ensuring that they stay the same test run after test run. It's far easier to fix inputs once and for all.&lt;/p&gt;

&lt;p&gt;When creating this type of test, we want to avoid moving or random values. Two of the most common are dates and UUIDs. While it's possible to generate UUIDs using external tools, there is room for improvement if you want to do everything directly in PhpStorm. Even if typing a date is not as painful, we can gain some time here too. &lt;/p&gt;

&lt;p&gt;PhpStorm, and probably all IntelliJ IDEs, allow creating Live templates. Live templates are templates that we can expand by typing an abbreviation and triggering the autocomplete. What's even more remarkable is that they can evaluate &lt;a href="https://www.jetbrains.com/help/phpstorm/template-variables.html#predefined_functions"&gt;expressions&lt;/a&gt; when the abbreviation is expanded. This is what we'll use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3KQbdCPb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsz6mgww1mc2v7blnw0p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3KQbdCPb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsz6mgww1mc2v7blnw0p.gif" alt="Generating dates and UUIDs with a only few keystrokes." width="860" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the current date
&lt;/h2&gt;

&lt;p&gt;For generating the current date, we can use the &lt;code&gt;date&lt;/code&gt; expression provided by PhpStorm and bind it to a variable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In PhpStorm settings, go to &lt;code&gt;Editor &amp;gt; Live Templates&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Expand the PHP section&lt;/li&gt;
&lt;li&gt;Click on the Add button, &lt;code&gt;+&lt;/code&gt; on the right side, and select &lt;code&gt;Live template&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the abbreviation field, enter &lt;code&gt;$date$&lt;/code&gt;. This is what we'll type to expand the template.&lt;/li&gt;
&lt;li&gt;In the template text field, enter &lt;code&gt;'$date$'$END$&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Edit variables&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the line for the variable named &lt;code&gt;date&lt;/code&gt;, add the expression &lt;code&gt;date("yyyy-MM-dd'T'HH:mm:ss.SSSz")&lt;/code&gt;  and select &lt;code&gt;Skip if defined&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Define&lt;/code&gt; below the &lt;code&gt; ⚠️ No applicable contexts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;PHP &amp;gt; Expression&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Save and close the settings with the &lt;code&gt;Ok&lt;/code&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Generating a random UUID
&lt;/h2&gt;

&lt;p&gt;Generating a UUID is slightly different because PhpStorm doesn't provide a function to create UUIDs directly, but it, fortunately, allows to run Groovy scripts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In PhpStorm settings, go to &lt;code&gt;Editor &amp;gt; Live Templates&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Expand the PHP section&lt;/li&gt;
&lt;li&gt;Click on the Add button, &lt;code&gt;+&lt;/code&gt; on the right side, and select &lt;code&gt;Live template&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the abbreviation field, enter &lt;code&gt;$uuid$&lt;/code&gt;. This is what we'll type to expand the template.&lt;/li&gt;
&lt;li&gt;In the template text field, enter &lt;code&gt;'$uuid$'$END$&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Edit variables&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the line for the variable named &lt;code&gt;uuid&lt;/code&gt;, add the expression &lt;code&gt;groovyScript("UUID.randomUUID().toString()")&lt;/code&gt; and select &lt;code&gt;Skip if defined&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Define&lt;/code&gt; below the &lt;code&gt;⚠️ No applicable contexts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;PHP &amp;gt; Expression&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Save and close the settings with the &lt;code&gt;Ok&lt;/code&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And voila, we now can quickly insert the current date or a UUID in our code.&lt;/p&gt;

&lt;p&gt;Thanks to PhpStorm allowing us to execute Groovy code, we can probably think of other ideas and save more time. For instance, it would probably make sense to generate a random date instead of the current one, as we could be in a particular case if the code has conditions based on the current date.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>php</category>
    </item>
    <item>
      <title>An alias to learn aliases</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Sun, 20 Jun 2021 13:46:56 +0000</pubDate>
      <link>https://dev.to/selrahcd/an-alias-to-learn-aliases-12m8</link>
      <guid>https://dev.to/selrahcd/an-alias-to-learn-aliases-12m8</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was previously posted on &lt;a href="https://blog.charlesdesneuf.com?utm_medium=social&amp;amp;utm_source=dev_to&amp;amp;utm_campaign=article-learn-aliases"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’m trying to save some time by reducing the number of keystrokes I need to do something.&lt;/p&gt;

&lt;p&gt;I’m pretty efficient with my IDE’s shortcuts, but I have vast room for improvement in my console.&lt;/p&gt;

&lt;p&gt;The obvious solution there is relying on aliases.&lt;/p&gt;

&lt;p&gt;I’ve been using the git ssh plugin for several years, but I only use a handful of the provided aliases, mostly because I never took the time to memorize past the few main ones.&lt;/p&gt;

&lt;p&gt;Now that I’m trying to save some typing, I’m learning the other ones. I have an issue, though: I spend a lot of time looking at the documentation to know which alias shortens the command I want to enter. In that case, it means I switch to my browser, get the right tab, or go to the website, use the search to find the suitable alias by typing part of the command. I don’t save a lot of keystrokes, and I’m surely not gaining time.&lt;/p&gt;

&lt;p&gt;Please don’t take me wrong; time spend learning or practicing to improve in the long run is time well spent. Nevertheless, I decided to find a way to enhance my learning process.&lt;/p&gt;

&lt;p&gt;The best way to reduce the amount of time needed to find the proper alias for a command is to stay in the console and avoid looking at the documentation.&lt;/p&gt;

&lt;p&gt;After a quick search, I discovered that the &lt;code&gt;alias&lt;/code&gt; command lists all aliases set up. That’s a start.&lt;/p&gt;

&lt;p&gt;Combining &lt;code&gt;alias&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; makes it efficient to find the correct alias for the job.&lt;/p&gt;

&lt;p&gt;That still requires some typing, if your shell doesn’t have some sort if autocomplete at least.&lt;/p&gt;

&lt;p&gt;As I’m in a quest for laziness and poking around with aliases, I decided to add a new one, &lt;code&gt;fa&lt;/code&gt;, for “find alias” defined as &lt;code&gt;alias fa='alias | grep'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An example: searching for all aliases about stash&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XbhtMLto--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a54b9m1mv8e9tktc3g9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XbhtMLto--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a54b9m1mv8e9tktc3g9v.png" alt="Typing fa stash returns a list of aliases containing stash" width="880" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just two letters, no more windows switching, and a lot of time saved.&lt;/p&gt;

&lt;p&gt;Do you have some tips about productivity as well?&lt;/p&gt;

</description>
      <category>bash</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Announcing Burritalks.io, a curated list of talks for product people</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Mon, 08 Feb 2021 17:00:31 +0000</pubDate>
      <link>https://dev.to/selrahcd/announcing-burritalks-io-a-curated-list-of-talks-for-product-people-1mk3</link>
      <guid>https://dev.to/selrahcd/announcing-burritalks-io-a-curated-list-of-talks-for-product-people-1mk3</guid>
      <description>&lt;p&gt;I read many books and blog posts and watch a lot of talks about software product creation. People I've worked with know that I always have resources to share on many subjects related to software product creation.&lt;/p&gt;

&lt;p&gt;I started keeping a list of exciting talks a few years ago. Speeches that made me think, gave me new perspectives or ideas, reshaped the way I think about building software, and helped me grow as a developer.&lt;/p&gt;

&lt;p&gt;After a while, I stopped adding items to the list. Even if it was public, no one was using it, not even me. It wasn't easy to find nor looking good. I decided to trust my memory and others medium - Twitter or Pocket - as good places to keep track of these talks. Time proved me wrong.&lt;/p&gt;

&lt;p&gt;I hope that creating and curating a website will help me commit to keeping track of them.&lt;/p&gt;

&lt;p&gt;The content is primarily oriented for developers. A lot of talks are about system architecture, testing, agile transformation, and choosing the right tool for the job.&lt;/p&gt;

&lt;p&gt;So, here it is: &lt;a href="https://www.burritalks.io/?&amp;lt;br&amp;gt;%0Autm_medium=social&amp;amp;utm_source=devto&amp;amp;utm_campaign=announce_post"&gt;Burritalks.io&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;I hope you'll get as many insights as I got from watching some of this content. Let me know what you think!&lt;/p&gt;

&lt;p&gt;Edit: fixed link 😅&lt;/p&gt;

</description>
      <category>techtalks</category>
      <category>news</category>
    </item>
    <item>
      <title>Faster environment with xDebug and Docker</title>
      <dc:creator>Charles</dc:creator>
      <pubDate>Tue, 19 Jan 2021 18:25:37 +0000</pubDate>
      <link>https://dev.to/selrahcd/faster-environment-with-xdebug-and-docker-366m</link>
      <guid>https://dev.to/selrahcd/faster-environment-with-xdebug-and-docker-366m</guid>
      <description>&lt;p&gt;I have to admit that I've always been lazy when it came to set up xDebug as it felt tedious the few times I've to do it. It made me an almost perpetual member of the &lt;code&gt;var_dump&lt;/code&gt; debug team.&lt;/p&gt;

&lt;p&gt;Nevertheless, the last time I had to set it up was more straightforward, thanks to PhpStorm, and I don't think the difficulty to set up is a valid excuse anymore.&lt;/p&gt;

&lt;p&gt;I then had a debugger…&lt;/p&gt;

&lt;p&gt;And I had a speed issue. My tests were running slower than before, and every request took way too much time. Using Docker on OSX didn't help at all.&lt;/p&gt;

&lt;p&gt;I found a few tips that helped me go back to the same state as before.&lt;/p&gt;

&lt;p&gt;So …&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips 1: Do not start xDebug
&lt;/h2&gt;

&lt;p&gt;Ahah… Yes, you can thank me for this one. The best way to avoid xDebug slowing everything down is by not having xDebug running. So, disable it by commenting the path to the extension in the .ini file loading it. Another idea is that if you have an xdebug.ini file in the PHP configuration directory, rename it to something else, xdebug.ini.back, for instance.&lt;/p&gt;

&lt;p&gt;This being said, how can we manage to start xDebug when needed?&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips 2: Use the on-demand PhpStorm mode when debugging tests
&lt;/h2&gt;

&lt;p&gt;As explained in the PhpStorm documentation, an "on-demand" mode is available. It will enable xDebug only when debugging tests, which will allow running your test at full speed most of the time.&lt;/p&gt;

&lt;p&gt;I'll let you dig in the documentation as it will be better explained than if I do it myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips 3: Use the on-demand mode without PhpStorm
&lt;/h2&gt;

&lt;p&gt;PhpStorm is not doing magic for the "on-demand" mode but taking advantage of the -d PHP CLI option. The -d allows defining an entry in the PHP configuration. When starting the "on-demand" mode, PhpStorm adds &lt;code&gt;-d zend_extension=xdebug.so&lt;/code&gt; to the PHP CLI options, which enables the extension. You can do the same thing if you're running your tests without PhpStorm.&lt;/p&gt;

&lt;p&gt;As an example here is how you can run PhpUnit with xDebug activated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;zend_extension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xdebug.so ./vendor/bin/phpunit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll probably need to pass more options if you want to connect xDebug to a debugger client, so this not as convenient as running it through PhpStorm as it sets everything needed to work out the box. As an example, here are all the option passed by PhpStorm when I start tests in debug mode :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;zend_extension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xdebug.so &lt;span class="nt"&gt;-d&lt;/span&gt; xdebug.remote_enable&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; xdebug.remote_mode&lt;span class="o"&gt;=&lt;/span&gt;req &lt;span class="nt"&gt;-d&lt;/span&gt; xdebug.remote_port&lt;span class="o"&gt;=&lt;/span&gt;9100 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; xdebug.remote_host&lt;span class="o"&gt;=&lt;/span&gt;host.docker.internal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is still a good option if you need xDebug without a client listening. I guess the primary use case would be for coverage reports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips 4: Enable xDebug with an environment variable in your docker container
&lt;/h2&gt;

&lt;p&gt;Going in the container and modifying files every time you need to enable or disable xDebug is cumbersome. I've tested another option for the last few weeks, and it works very well.&lt;/p&gt;

&lt;p&gt;I've modified my PHP Dockerfile to add an entry point script, which is run when the container starts and can access environment variables.&lt;/p&gt;

&lt;p&gt;The entry point script looks for an environment variable and decides to rename, or not, the xdebug.ini file in the PHP configuration directory.&lt;/p&gt;

&lt;p&gt;As an example, here is the &lt;code&gt;entrypoint.sh&lt;/code&gt; file I'm using in a php5.6 container. You'll probably need to adapt it to suit your container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DISABLE_XDEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DISABLE_XDEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/etc/php/5.6/mods-available/xdebug.ini"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then

&lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; /etc/php/5.6/mods-available/xdebug.ini /etc/php/5.6/mods-available/xdebug.ini.back

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
⚠️  xDebug is disabled
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DISABLE_XDEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DISABLE_XDEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/etc/php/5.6/mods-available/xdebug.ini.back"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
&lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; /etc/php/5.6/mods-available/xdebug.ini.back /etc/php/5.6/mods-available/xdebug.ini
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
And the Dockefile is edited to include the entry point:

COPY ./entrypoint.sh /
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/entrypoint.sh"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"php-fpm5.6"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container can be started either with docker-compose or docker run and xDebug activated by setting the environment variable DISABLE_XDEBUG to false and disabled by setting it to true. When the variable is missing, xDebug will stay activated.&lt;/p&gt;

&lt;p&gt;We now have a convenient way to enable xDebug only when needed and save some precious time not waiting in front of loading pages. The only thing required is to change the value of the variable and restart the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra tip
&lt;/h2&gt;

&lt;p&gt;xDebug settings can be overridden using the XDEBUG_CONFIG environment variable, which means there is no need to update the xDebug config file every time you have to change a setting or if you and your teammates need different settings.&lt;/p&gt;

&lt;p&gt;The best example is probably the &lt;code&gt;remote_host&lt;/code&gt;. According to how you run docker, this setting could be a changing IP address or &lt;code&gt;host.docker.internal&lt;/code&gt; if you're using Docker for Mac.&lt;/p&gt;

&lt;p&gt;In order to set the remote host to &lt;code&gt;host.docker.internal&lt;/code&gt; the &lt;code&gt;XDEBUG_CONFIG&lt;/code&gt; should be set &lt;code&gt;remote_host=host.docker.internal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I hope all these tips will help you improve the speed of your development environment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally posted on &lt;a href="https://blog.charlesdesneuf.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=article+faster+environment+with+xDebug+and+Docker"&gt;my blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Picture by &lt;a href="https://unsplash.com/photos/53B17GiIhTA"&gt;Paolo Candelo&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>php</category>
      <category>phpstorm</category>
    </item>
  </channel>
</rss>
