<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="https://adelinasimion.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://adelinasimion.dev/" rel="alternate" type="text/html" /><updated>2024-03-09T18:32:44+00:00</updated><id>https://adelinasimion.dev/feed.xml</id><title type="html">Adelina Simion</title><subtitle>Technology Evangelist</subtitle><entry><title type="html">Craft Yourself a Sustainable Tech Career</title><link href="https://adelinasimion.dev/jobs/iwd-reflections/" rel="alternate" type="text/html" title="Craft Yourself a Sustainable Tech Career" /><published>2024-03-09T00:00:00+00:00</published><updated>2024-03-09T00:00:00+00:00</updated><id>https://adelinasimion.dev/jobs/iwd-reflections</id><content type="html" xml:base="https://adelinasimion.dev/jobs/iwd-reflections/"><![CDATA[<p>This year marks my tenth anniversary of working in tech. I graduated from university in Denmark at the end of 2013. I moved to London in the spring of 2014 and took a graduate Java developer position. Except for the odd 1-2 month break between jobs, I have been working full time in the past decade.</p>

<p>I take immense pride in my career and my achievements, but the road has not been easy. Sometimes others wanted me to fail, sometimes I doubted myself, and sometimes I dreamt about packing it all in. But here I am, a decade later… still standing! 💪</p>

<p>When it comes to your career, the race is an ultra-marathon through the desert in cheap shoes, not a nice jog on a manicured lawn. Keeping a sustainable pace is the key to success.</p>

<p>This post is a collection of lessons that I learned the hard way, which helped me stay consistent and show up another day. I hope they will also help you.</p>

<p>💐 <strong>Happy International Women’s Day!</strong> 💐</p>

<h2 id="you-dont-have-to-be-beyond-reproach">You don’t have to be beyond reproach.</h2>

<p>When I first started as an engineer, I felt like I could not make any mistakes and my work should be the best I could possibly deliver. <em>“Push yourself, work harder than everyone else, show them that you mean business!”</em>  became the mantra that I would repeat to myself every day. Of course, this affected my mental health, pushed me to drink alcohol to cope with anxiety and stopped me from learning. Within the first two years, I was miserable and questioning my career choice.</p>

<p>True equality in tech does not mean that the minorities need to be better than everyone else, but still get paid the same. You are allowed the same grace and understanding as your peers.</p>
<ul>
  <li>You are allowed to make the same mistakes.</li>
  <li>You are allowed learn at the same pace.</li>
  <li>You should be given as many chances and opportunities.</li>
</ul>

<p>Your place in tech is just as valid as everyone else’s. You don’t need to outperform to be worthy. Give yourself the space to make mistakes and learn from them, so that you can grow and have a sustainable tech career.</p>

<h2 id="never-make-yourself-small">Never make yourself small.</h2>

<p>I worked in-office jobs up until the pandemic in 2020. Six years of 2hr travel time each day. Six LONG years of showing up to the office every day and having to sit through in-person meetings. When I attended meetings, I would sit in the back, pull my shoulders forward, and hope that nobody talks to me. Typically, I didn’t speak in these meetings. On the rare occassions that I did, I would state my opinions as questions, hesitantly and unconfidently. I made myself <em>small</em>.</p>

<p>When you feel like you don’t belong, you don’t want to be noticed or singled out. However, people who don’t get noticed also don’t get given interesting opportunities, don’t get promoted and they definitely don’t get raises. <em>Trust me, I know.</em></p>

<p>It can be helpful to imagine you are playing a part, a <em>work persona</em>. You can imagine who this person is, the kind of questions they ask and how they are perceived by others. Then, use your imagination to apply your mannerisms to your work persona. You are playing the part of a lifetime, so you’ve got to sell it! As you reconcile image of yourself and your work personna, you begin to show up to work in a confident way. The work personna is a crutch you won’t need forever, but it will allow you to let go of your perceived limitations.</p>

<p>As I mentioned in the previous section, you should never question your place in tech. You should be free to ask questions and voice your opinions when you go to meetings as well. Your thoughts are worth just as much as everyone else’s, so don’t hold them back. Getting noticed, demonstrating leadership and confidence, will craft you a sustainable tech career by setting you up for success when the next performance review comes around. 🤞</p>

<h2 id="you-are-not-an-impostor">You are not an impostor.</h2>

<p>At the beginning of my career, I was fully convinced that I was the person in the room that knew the least. That was fine because I was going to work extra hard and get better. Being a newly minted junior engineer is extremely liberating. Your job is quite simple: soak up knowledge, deliver work as instructed, and keep improving. This freedom doesn’t last, so make sure you enjoy every minute of it. As you get experience and credibility, the expectations of those around you increase. It was around the four-year experience mark that I first experienced the dreaded <em>impostor syndrome</em>, even though I did not know how to verbalise it.</p>

<p>Impostor syndrome warps all of your experiences, as if through a skewed magnifying glass. All of your achievements are minimised, all of your little failures are catastrophised and everyone around you appears to be effortlessly better than you. As these warped thoughts constantly swirl around in your head, the impostor syndrome is reinforced and the magnifying glass gets stronger.</p>

<p>At my lowest point, I thought I was sure to be let go on the basis of performance. I walked into my performance review expecting the worst. I was absolutely ecstatic when I got a <em>meets expectations</em>! It was then that I realised how warped my thinking had become.</p>

<p>The best weapon you have against impostor syndrome is <em>reality</em>.</p>
<ul>
  <li>Start to write down every thing you do well and everything you learn, no matter how small.</li>
  <li>Document your wins even when it feels like you have nothing to celebrate.</li>
  <li>As the practice of celebrating your small wins becomes habit, you will see your improvements and begin to advocate for yourself.</li>
</ul>

<p>In my experience, this process will help dismantle the impostor syndrome that has taken hold of your thinking patterns. You will begin to believe your own track record and improve your self confidence.</p>

<p>Impostor syndrome can cause a lot of people, especially minorities, to feel alienated and eventually leave tech. You can overcome it! Check out <a href="https://www.calm.com/blog/how-to-overcome-imposter-syndrome">this page from the Calm blog</a> for more techniques.</p>

<h2 id="lift-yourself-by-lifting-others">Lift yourself by lifting others.</h2>

<p>As I look back at my career, I don’t remember code, tickets or problems. I remember the people I met along the way and the impact we had on each others’ lives. I think that’s really lovely. 🫶</p>

<p>Make it your priority to support others, in little or big ways. Show up for others, be compassionate and build a support network around yourself. Even in a larger city like London, I have found that tech is a quite small community. It’s quite handy to have friends in important rooms. 💪</p>

<p>If you’re not sure where to start, get involved with your local tech communities on meetup or engage online. I’m a firm believer in fostering in-person relationships though, so do try to cultivate a professional network in your area, not rely solely on online connections.</p>

<p>Working in tech can be lonely and difficult due to the complex nature of the work. Fostering connections with others will make you feel like you belong, as well as provide support to those around you. A sustainable tech career isn’t nurtured in isolation and you are not an island. 🏝️ Personal relationships are sometimes even more important than your technical skills.</p>

<h2 id="parting-thoughts">Parting Thoughts</h2>

<p>I can’t believe it’s already been TEN YEARS since I started my career. The last thought I’d like to leave you with is that <em>if I can do it, so can you</em>. It doesn’t matter whether you are trying to get your first job in tech or are looking for a new opportunity following a redundancy, you will find your next opportunity.</p>

<p>We can do hard things and will overcome whatever this ultra-marathon in the desert throws at us. 🏜️</p>

<div class="container">
    <div class="row">
        <figure class="centered">
          <iframe src="https://giphy.com/embed/Q21Nnq7Qjem0QsC4Fp" width="480" height="300" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/onepeloton-Q21Nnq7Qjem0QsC4Fp">via GIPHY</a></p>
        </figure>
    </div>
</div>]]></content><author><name></name></author><category term="jobs" /><category term="SheCoded" /><category term="career" /><summary type="html"><![CDATA[This year marks my tenth anniversary of working in tech. Except for the odd 1-2 month break between jobs, I have been working full time in the past decade. I take immense pride in my career and my achievements, but the road has not been easy. When it comes to your career, the race is an ultra-marathon through the desert in cheap shoes, not a nice jog on a manicured lawn. Keeping a sustainable pace is the key to success. This post is a collection of lessons that I learned the hard way, which helped me stay consistent and show up another day. I hope they will also help you. 💐 Happy International Women's Day! 💐]]></summary></entry><entry><title type="html">All Gophers aboard! Deploying your first Go app to Railway 🛤️</title><link href="https://adelinasimion.dev/go/railway-go-app/" rel="alternate" type="text/html" title="All Gophers aboard! Deploying your first Go app to Railway 🛤️" /><published>2023-08-23T00:00:00+00:00</published><updated>2023-08-23T00:00:00+00:00</updated><id>https://adelinasimion.dev/go/railway-go-app</id><content type="html" xml:base="https://adelinasimion.dev/go/railway-go-app/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        11 mins
    
  </p>
</div>

<p>Railway is a modern PaaS solution that makes deploying code easier. I’ve had a bit of time to experiment with it and was keen to write up my findings for how it worked with Go projects. In this post, I explore the magic of its deployment mechanisms and demonstrate how to use GitHub Actions to deploy code to Railway. <strong>Spoiler alert</strong> : I loved learning about Railway and will be building with it more in the future!</p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/9PxpzVxz4aNTbz0DaR/giphy.gif" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/9PxpzVxz4aNTbz0DaR/giphy.gif" alt="Love it!" />
            </a>
        </figure>
    </div>
</div>

<h2 id="what-is-railway-️">What is Railway? 🛤️</h2>
<p><a href="https://railway.app/">Railway</a> is often <a href="https://docs.railway.app/reference/compare-to-heroku">compared to Heroku</a> because it makes the provisioning of infrastructure and deployment of code much easier than other public cloud providers. This is perfect for me, a backend engineer who wants to build stuff!</p>

<p>Here are some of the key headline features of the platform:</p>

<ol>
  <li><strong>Zero configuration builds</strong> : the Railway team have started the <a href="https://github.com/railwayapp/nixpacks">Nixpacks</a> project. This project builds OCI compliant images based on the source repository. They currently support a variety of <a href="https://docs.railway.app/deploy/builds">popular languages</a> out of the box, including Go ⭐️ of course! For other languages, you can supply your own Docker file and still run on Railway.</li>
  <li><strong>In-built GitHub support</strong> : Railway services can be tied to a GitHub repository. Then, changes committed to configured branches automatically trigger services to be re-deployed. The cherry on top 🍒 is that the Railway CLI also makes it easy to configure GitHub Actions workflows. I will show you how this works later on in this post.</li>
  <li><strong>Secrets management</strong> : once deployed, Railway services are organised into environments, which then belong to projects. You can easily configure project secrets which are <em>shared</em> between different services in the same project. Services can also have their own defined secrets. This approach to secrets management gives you a lot of configuration flexibility.</li>
  <li><strong>Templates</strong> : the Railway team and community have created templates for even easier code deployment. You can create a project from a template, which then creates a public GitHub repo using your GitHub user. This repository is then linked to a Railway service using the previously mentioned GitHub support. At the time of writing, there are templates for the most popular Go web frameworks: <a href="https://gofiber.io/">fiber</a>, <a href="https://gin-gonic.com/">gin</a>, <a href="https://pkg.go.dev/github.com/gorilla/mux">gorilla/mux</a> and <a href="https://go-chi.io/#/">chi</a>. The big advantage of using a template is that you will also receive updates when the template itself is updated. Railway also runs an <a href="https://railway.app/open-source-kickback">OSS kickback programme</a> which gives back 25% of template usage revenue to the template creators. That’s a great incentive for the Go community to extend Railway support! 🤑</li>
</ol>

<p>Now that I have covered the fundamentals of Railway, let’s get hands on and see how easy it <em>really</em> is to run on Railway! 🚆</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <a href="https://railway.app/" target="_blank">
                <img class="centered" src="/assets/railway/railway-banner.png" alt="Railway banner" />
            </a>
        </figure>
    </div>
</div>

<h2 id="signing-up--setting-up-️">Signing up &amp; setting up 🛠️</h2>
<p>As you might imagine, signing up and onboarding are pretty painless. When creating an account, you can choose to sign up via email or using your GitHub account. I would recommend using your GitHub account, as that will also add Railway as a <a href="https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps">GitHub app</a>, which will make it easier for you to leverage GitHub integrations later on. Once signed up, you will be put on the Trial plan which will give you a free $5 allowance to explore Railway with. <a href="https://railway.app/pricing">Pricing</a> then starts from $5 a month with the Hobby plan.</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <a href="https://railway.app/pricing" target="_blank">
                <img class="centered" src="/assets/railway/railway-pricing.png" alt="Railway pricing" />
            </a>
        </figure>
    </div>
</div>

<p>Once you’re all set up, you can create a new project from your <a href="https://railway.app/dashboard">dashboard</a> or through the <a href="https://docs.railway.app/develop/cli">Railway CLI</a>. Since I’ve never been a fan of ClickOps, I’ll do as much as possible using the CLI, even though the dashboard is easy to use and inspect. The CLI can be installed in a <a href="https://docs.railway.app/develop/cli#installation/">variety of ways</a> depending on your OS. I installed it using <a href="https://brew.sh/">homebrew</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ brew install railway
</code></pre></div></div>
<p>Once installed, you will need to authenticate your CLI session in your terminal:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ railway login
</code></pre></div></div>
<p>This command will authenticate you using the browser, but there is also a <code class="language-plaintext highlighter-rouge">-browserless</code> option.</p>

<p>As previously mentioned, Railway organises your work in projects. I must now create a new project which can be the home of my upcoming deployments:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ railway init
&gt; Project Name Will be randomly generated
Created project sneaky-window on Personal
https://railway.app/project/ee5d0509-b356-4581-a5af-d4dfcce84001
</code></pre></div></div>
<p>You can provide a name for your project or have a random one generated as above. A URL to inspect your project on the dashboard is also printed out. <em>By the time this blogpost publishes, this project will have already been torn down, but it might be a good idea to keep this key secret!</em></p>

<p>By default, all projects have a generated <code class="language-plaintext highlighter-rouge">production</code> environment. All Railway <a href="https://docs.railway.app/develop/environments">environments</a> contain the same services, but give you isolated instances that you can experiment on separately. You can create new environments using the Railway dashboard, but can then change between them from the CLI. A really neat feature is that environments can be <a href="https://docs.railway.app/develop/environments#forking-and-merging-environments">forked and merged</a> as well. Going forward, I’ll only be working in the default <code class="language-plaintext highlighter-rouge">production</code> environment.</p>

<p>That’s all the setup you need for now: you’ve signed up to Railway, set up your CLI for easier management and created a new project that you can deploy your work to. It’s time to get some Go code ready for deployment! 🚀</p>

<h2 id="the-go-european-weather-checker-">The Go European Weather checker 🇪🇺</h2>
<p>I’ve written a small Go app that displays the weather in the European capitals as part of this Railway experiment. You can see it on GitHub at <a href="https://github.com/addetz/go-weather-checker">addetz/go-weather-checker</a>. I have written this app from scratch, but I could have used one of the Railway Go templates as the starting point.</p>

<p>This little application uses the following technologies:</p>

<ul>
  <li><a href="https://github.com/labstack/echo">labstack/echo</a> is my chosen web framework. I’ve recently started using this framework and I really like how easy it is to configure routes, as well as construct JSON responses.</li>
  <li><a href="https://github.com/gopherjs/gopherjs">GopherJS</a> compiles Go code to JavaScript. I built a very small frontend to make the demo more visually appealing. This library allowed me to build the entire demo in Go, except for some simple HTML. The frontend is styled with <a href="https://getbootstrap.com/">bootstrap</a>.</li>
  <li><a href="https://openweathermap.org/">OpenWeatherMap</a> is the third-party service that I use to fetch weather data. This service provides you with 1000 free API calls per day. As part of sign up, you will be issued with an API key that you can use for querying.</li>
</ul>

<p>The application is configured with 2 environment variables: the OpenWeatherMap API key mentioned above is mandatory and the port is optional, with a default value of <code class="language-plaintext highlighter-rouge">8080</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">export </span><span class="nv">WEATHER_API_KEY</span><span class="o">=</span>XXX
<span class="nv">$ </span><span class="nb">export </span><span class="nv">PORT</span><span class="o">=</span>XXX
</code></pre></div></div>

<p>After setting our variables, the server runs like any old server:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>go run server.go

</code></pre></div></div>

<p>Once the server starts up, you can navigate to it in the browser at <code class="language-plaintext highlighter-rouge">localhost:8080</code> or whatever port you have configured. Now you can see what the weather is in any European capital! 😎</p>

<div class="row">
  <div class="col-full">
    <div class="talks-title">The Go European Weather Checker in action! ​</div>
    <div class="talks-video-container">
      <iframe src="https://drive.google.com/file/d/1rDZA-QAs3XSL0FF4YprHsszcrbqGbQkJ/preview" width="640" height="480" allow="autoplay"></iframe>
    </div>
  </div>
</div>

<h2 id="deploying-to-railway-">Deploying to Railway 🚆</h2>
<p>As mentioned above, the source for my app is at <a href="https://github.com/addetz/go-weather-checker">addetz/go-weather-checker</a>. The repo does not have a Dockerfile, but it does contain a <code class="language-plaintext highlighter-rouge">go.mod</code> file which will signal to Nixpacks that this is a Go application.</p>

<p>Back in my terminal, I link the repo root directory of the weather app with the previously created <code class="language-plaintext highlighter-rouge">sneaky-window</code> project and its default created <code class="language-plaintext highlighter-rouge">production</code> environment:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>railway <span class="nb">link</span>
<span class="o">&gt;</span> Select a project sneaky-window
<span class="o">&gt;</span> Select an environment production

</code></pre></div></div>

<p>Linking my CLI session to this project allows me to run all future commands against this project and environment. I can then easily deploy the weather app using the <code class="language-plaintext highlighter-rouge">up</code> command:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>railway up

</code></pre></div></div>

<p>At this point, Nixpacks will build and publish an image for my app and Railway will attempt to start a service running  its built image. However, this service will immediately crash because I have not set up any secrets for my application. The deploy logs simply print the following and the application exits. 😱</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2023/08/24 14:22:33 WEATHER_API_KEY must be set
</code></pre></div></div>

<p>At the time of writing, the Railway team are <a href="https://docs.railway.app/develop/cli#cli-v3-changes">rethinking the secrets workflow within the CLI</a>, so I am not be able to add the mandatory secret from the terminal. Instead, I add it as a <a href="https://docs.railway.app/develop/variables#shared-variables">shared variable</a> to the project by navigating to the <a href="https://railway.app/dashboard">Railway dashboard</a> and adding it to the project settings, then sharing it with the newly created weather service.</p>

<div class="container">
    <div class="row">
      <figure class="centered">
          <img class="centered" src="/assets/railway/railway-shared-variables.png" alt="Railway shared variables" />
        </figure>
    </div>
</div>

<p>Once this variable is shared, the service will be successfully redeployed:</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <img class="centered" src="/assets/railway/railway-success-deploy.png" alt="Railway success deploy" />
        </figure>
    </div>
</div>

<p>The running deployment shows us two things:</p>

<ul>
  <li>Railway is able to detect that I am attempting to expose a webserver.</li>
  <li>The app is now listening on port <code class="language-plaintext highlighter-rouge">:5784</code>, even though this has not been configured at all.</li>
</ul>

<p><strong>How on earth is this all happening?</strong> 🧐</p>

<p>The secret lies in the magic 🪄 of Railway, of course… and the <code class="language-plaintext highlighter-rouge">PORT</code> environment variable. In order to <a href="https://docs.railway.app/deploy/exposing-your-app">expose web apps</a>, Railway needs an IP and port. The IP is provided through configured domains, while the port is configured through a Railway provided <code class="language-plaintext highlighter-rouge">PORT</code> environment variable. If any apps you write are configured to use this variable, they will be able to expose endpoints to the internet without any further configuration.</p>

<p>There are 2 options for domain configuration: generate one or add a custom domain from the service settings. In this instance, I have generated a domain and my app will be exposed at <code class="language-plaintext highlighter-rouge">https://sneaky-window-production.up.railway.app/</code>. One really neat thing to notice is that Railway has also secured all traffic to my application with HTTPS without me having to configure anything in my app or create certificates. Nixpacks took care of that. 🤩</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <img class="centered" src="/assets/railway/railway-expose.png" alt="Railway success deploy" />
        </figure>
    </div>
</div>

<h2 id="the-cherry-on-top--github-actions">The cherry on top 🍒: GitHub Actions</h2>
<p>As a final step, let’s talk about CI/CD with <a href="https://github.com/features/actions">GitHub Actions</a>. Workflow configuration and management have now become synonymous with GitHub Actions, so of course it makes sense that Railway supports this!</p>

<p>Railway allows the creation of project tokens in order to authenticate from remotes where even browserless login is not possible. You can create a new token from the <em>Tokens</em> tab of your project settings. This token will give you programmatic access to the project.</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <img class="centered" src="/assets/railway/railway-token.png" alt="Railway expose web server" />
        </figure>
    </div>
</div>

<p>On the GitHub side, I add this token as a secret to the weather app repository <a href="https://github.com/addetz/go-weather-checker">addetz/go-weather-checker</a> by navigating to <em>Settings</em> -&gt; <em>Secrets and Variables</em> -&gt; <em>Actions</em>. I will name this token <code class="language-plaintext highlighter-rouge">RAILWAY_TOKEN</code> as advised. I have also added a further secret called <code class="language-plaintext highlighter-rouge">RAILWAY_SERVICE</code>, which will allow me to instruct which service to deploy this repository to.</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <img class="centered" src="/assets/railway/railway-gha-secret.png" alt="Railway GHA token" />
        </figure>
    </div>
</div>

<p>You are now ready to run GitHub Actions with Railway! A simple workflow which builds our app, runs our tests and then deploys the code using Railway can be seen below:</p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to Railway</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">main</span><span class="pi">]</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">deploy</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Go</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-go@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">go-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">1.21.x'</span>
    
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install dependencies</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">go get ./...</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">go build -v ./...</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Test with the Go CLI</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">go test ./... -v</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy Railway</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">bervProject/railway-deploy@main</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">railway_token</span><span class="pi">:</span>  <span class="s">${{ secrets.RAILWAY_TOKEN }}</span> 
          <span class="na">service</span><span class="pi">:</span>  <span class="s">${{ secrets.RAILWAY_SERVICE }}</span> 
</code></pre></div></div>

<p>I deploy to Railway using an existing <a href="https://github.com/bervProject/railway-deploy">railway-deploy GitHub Action</a>, which wraps around the installation aspects of the CLI. I make use of the configured repository variables to pass the token and the deployment service.</p>

<p>That’s all you need to seamlessly deploy your application to Railway with GitHub Actions. One aspect I have not covered is the ability to specify a GitHub repository as the service source, which will allow Railway to monitor the repository for changes on a configured branch, typically <code class="language-plaintext highlighter-rouge">main</code>, and then redeploy when new commits are made. You can read more about service sources and triggers on the <a href="https://docs.railway.app/develop/services#service-source">Railway docs</a>. I prefer to have control of deployments using GitHub Actions.</p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <img class="centered" src="/assets/railway/railway-executed-actions.png" alt="Railway executed actions" />
        </figure>
    </div>
</div>

<h2 id="parting-words">Parting words</h2>
<p>This brings me to the end of my exploration with Railway! It’s been so interesting to learn about this great platform. There is a lot here that can make our lives easier and help us ship projects faster, so I hope this post will inspire you to explore Railway on your own as well.</p>

<p>I’ll be following up with a post on how databases &amp; storage work in Railway, so stay tuned for that. And who knows… I might put forward an <code class="language-plaintext highlighter-rouge">echo</code> Railway template as well! 🤩</p>

<p><strong>Happy coding, Gophers!❤️</strong></p>]]></content><author><name></name></author><category term="go" /><category term="go" /><category term="railway" /><category term="code" /><summary type="html"><![CDATA[Railway is a modern PaaS solution that makes deploying code easier. I’ve had a bit of time to experiment with it and was keen to write up my findings for how it worked with Go projects. In this post, I explore the magic of its deployment mechanisms and demonstrate how to use GitHub Actions to deploy code to Railway. Spoiler alert - I loved learning about Railway and will be building with it more in the future!]]></summary></entry><entry><title type="html">Test-Driven Development in Go: principles and key concepts</title><link href="https://adelinasimion.dev/go/tdd-in-go/" rel="alternate" type="text/html" title="Test-Driven Development in Go: principles and key concepts" /><published>2023-05-06T00:00:00+00:00</published><updated>2023-05-06T00:00:00+00:00</updated><id>https://adelinasimion.dev/go/tdd-in-go</id><content type="html" xml:base="https://adelinasimion.dev/go/tdd-in-go/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        8 mins
    
  </p>
</div>

<p>I recently had the pleasure of discussing and demonstrating some of the key concepts of my <a href="https://bit.ly/3UFpweU">“Test-Driven Development in Go”</a> book on <a href="https://bit.ly/3HG9oVh">a live stream</a>. This post summarises the main points covered by this 1hr coding session. Understanding these testing essentials will go a long way to helping you become a TDD practitioner.</p>

<p><strong>Read on to see why you should care about testing and TDD!</strong></p>

<div class="row">
  <div class="col-full">
    <div class="talks-title">​Nikita Koselev: TDD in Go​</div>
    <div class="talks-video-container">
      <iframe src="https://www.youtube.com/embed/46ZjWWtY6Qo" title="YouTube video player" frameborder="0" allowfullscreen=""></iframe>
    </div>
  </div>
</div>

<h2 id="key-principles">Key principles</h2>

<p>I was keen to explore the topic of TDD in Go because it was one of the parts of the language that I had a hard time understanding, despite its simplicity. There were only a few functions available in Go’s <code class="language-plaintext highlighter-rouge">testing</code> package, but  I was unsure how to use them and it seemed difficult to build any test setup. Figuring out the testing process in Go took some time, especially as most tutorials are aimed at learning language basics, not test basics. I was keen to dedicate time share my knowledge, discover new concepts myself and write a thorough guide to writing testable code with <code class="language-plaintext highlighter-rouge">TDD</code> as the working process. This is why I took on the project of writing a book dedicated to testing techniques and the application of TDD.</p>

<p>The book is structured around the following four basic principles:</p>
<ul>
  <li><strong>Writing testable code starts with a thorough understanding of the language you are writing in</strong>: we need to understand the main structure and concepts of Go in order to be able to write testable code. We need to have a clear understating of concepts such as package structure, dependency injection, concurrency and more.</li>
  <li><strong>TDD is hard because it is difficult to have a clear vision of what we are trying to achieve when problems are ambiguous</strong>: writing tests is easy in Go, as we use the same techniques as writing source code. Instead, the unclear understanding of the work we are trying to achieve and an over fixation on technical solutions is what makes it difficult to practice TDD.</li>
  <li><strong>Engineers should take ownership of testing their product at all levels, not just unit</strong>: testing blogs &amp; demos often focus on unit testing only. While this makes it easy for developers to write tests with small scope, engineers should take ownership of testing at all levels. This has the benefit of giving us a thorough understanding of how users will be ultimately interacting with our product, but also give us ownership of our product in a true DevOps way.</li>
  <li><strong>Practicing TDD can help you organise your work and stay focused on solutions to user-problems</strong>: the TDD process involves writing tests alongside the source code. This encourages us to make conscious decisions for code structure that is focused on requirements and inputs, as opposed to get overly attached to technical solutions.</li>
</ul>

<p>Tests are typically organised in the <strong>testing pyramid</strong>:</p>
<ol>
  <li>At the bottom of the pyramid, we have <strong>unit tests</strong>, which only test a single, isolated behaviour or piece of functionality. They are the fastest and most numerous.</li>
  <li>In the middle, we have <strong>integration tests</strong>, which test the behaviour of multiple components together. They are complementary to unit tests, as they ensure that multiple units work well together not just individually.</li>
  <li>At the top of the pyramid, we have <strong>end-to-end tests</strong>, which test the entire application. They are typically focused on validating the application exposes the correct user-facing functionality.</li>
</ol>

<div class="container">
    <div class="row">
        <figure class="centered">
          <img class="fullSize" src="/assets/tdd/testing_pyramid.png" alt="Testing pyramid" />
          <figcaption class="imgcap"><i>The core principles of the book</i></figcaption>
        </figure>
    </div>
</div>

<h2 id="the-method">The method</h2>

<p>The Red-Green-Refactor method is the working process for TDD. It the three steps described in the figure below. In the beginning, it might be cumbersome to swap between source code and test code, but it will quickly become second nature. The three steps of the method are:</p>
<ol>
  <li><strong>The Red phase</strong>: based on provided requirements, we begin by writing a test with specified inputs and expected outputs. We run this test to ensure it is failing. This helps us avoid any false positives later on.</li>
  <li><strong>The Green phase</strong>: swapping over to source code, we write enough code to satisfy the previously written test and implement the functionality required. We re-run this test to ensure that it is now passing.</li>
  <li><strong>The Refactor phase</strong>: while the test and implementation are successfully fulfilling the requirement we have been focusing on, we can take the time to make any improvements to it in the refactor phase.</li>
  <li>The process repeats until we have successfully implemented all functionality that the unit requires.</li>
</ol>

<p>Tests should <strong>focus on testing outputs, not implementation</strong>. If tests are tightly coupled implementation concerns,they can become brittle when code is changed or refactored. Tests should be made as resilient to change as possible.</p>

<div class="container">
    <div class="row">
        <figure class="centered">
          <img class="fullSize" src="/assets/tdd/red_green_refactor.png" alt="Red-Green-Refactor" />
          <figcaption class="imgcap"><i>The Red-Green-Refactor TDD method</i></figcaption>
        </figure>
    </div>
</div>

<h2 id="unit-testing-essentials">Unit testing essentials</h2>

<p>Now that the process and main mechanisms are established, we can start to look at how to implement our first test. We begin at the bottom of the testing pyramid with unit tests.</p>

<p>Go functions, structs, variables and interfaces are organised in Go packages. Their visibility is restricted to the package unless exported with a capital letter. Directories can generally only contain a single package with some exceptions. One of these exceptions are <strong>testing packages</strong>. These packages end with the <code class="language-plaintext highlighter-rouge">_test</code> suffix and must match the name of the source package that is also defined in the same directory. These packages behave like any other external package, only having access to the exported names of the source package.</p>

<p>This is a very powerful mechanism. The usage of a test package ensures that we only test the externally visible functionality of the package, making our tests the first consumers of the package we are creating. We can then clearly identify what parts of exposed functionality need to be rewritten or clarified.</p>

<p>In Go, tests are just regular functions which comply to some restrictions:</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">TestName</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
  <span class="c">// implementation</span>
<span class="p">}</span>
</code></pre></div></div>
<ul>
  <li>Test names start with the <code class="language-plaintext highlighter-rouge">Test</code> prefix followed by the test name in camel case.</li>
  <li>Test functions take a single parameter of type <code class="language-plaintext highlighter-rouge">*testing.T</code>.</li>
  <li>Tests live in <code class="language-plaintext highlighter-rouge">_test.go</code> files.</li>
</ul>

<p>The <code class="language-plaintext highlighter-rouge">testing</code> package exposes methods logging and failing tests. The <code class="language-plaintext highlighter-rouge">t.Error</code> method fails a test but continues running the test suite, while the <code class="language-plaintext highlighter-rouge">t.Fatal</code> method fails the test and stops the execution of the entire test suite. The <code class="language-plaintext highlighter-rouge">t.Errorf</code> and <code class="language-plaintext highlighter-rouge">t.Fatalf</code> method counterparts which allow us to pass messages for formatting.</p>

<div class="container">
    <div class="row">
        <figure class="centered">
          <img class="fullSize" src="/assets/tdd/unit_testing.png" alt="Unit testing essentials" />
          <figcaption class="imgcap"><i>Getting started with Go unit tests</i></figcaption>
        </figure>
    </div>
</div>

<p>I demonstrate the <strong>Red-Green-Refactor</strong> method with a simple example and unit tests in the <a href="https://www.youtube.com/live/46ZjWWtY6Qo?feature=share&amp;t=550">live stream from timestamp 09:10</a>.</p>

<h2 id="integration-testing">Integration testing</h2>

<p>Unit tests do not have sufficient scope to ensure that functional requirements are successfully delivered. Often times, their implementation requires the usage of multiple units or <strong>components</strong> working together, delivering their specialised functionality in order to build the solution. In these cases, integration tests are often times a useful way to extend scope:</p>
<ul>
  <li>Integration tests cover one or multiple components, ensuring that the individual components work well as a combined entity. In the microservices world, the different components might even be delivered by different teams. The integrations between these separate units are often the cause of errors or outages.</li>
  <li>While the logic of the particular component is verified by its unit tests, the purpose of the integration test is to exercise the conditions at the seams between the components.</li>
  <li>Integration tests have the advantage of allowing us to test bigger scope, without the complexity of having to run an entire application. As they are in the middle of the pyramid, they don’t require the entire application to be ready for running and testing.</li>
</ul>

<div class="container">
    <div class="row">
        <figure class="centered">
          <img class="fullSize" src="/assets/tdd/integration_testing.png" alt="Integration tests" />
          <figcaption class="imgcap"><i>Integration tests allow us to test how well components work together</i></figcaption>
        </figure>
    </div>
</div>

<p>The code required for implementing integration tests isn’t any different from unit tests. I demonstrate writing integration tests using <code class="language-plaintext highlighter-rouge">httptest</code> in the <a href="https://www.youtube.com/live/46ZjWWtY6Qo?feature=share&amp;t=2678">live stream from timestamp 44:38</a>.</p>

<h2 id="end-to-end-testing">End-to-end testing</h2>

<p>This stream did not cover end-to-end testing. I may dedicate a future blogpost to this topic, but in the meantime, I recommend that you explore <a href="https://github.com/cucumber/godog">BDD testing with <code class="language-plaintext highlighter-rouge">godog</code></a> and <a href="https://github.com/pact-foundation/pact-go">contract testing with <code class="language-plaintext highlighter-rouge">pact</code></a>.</p>

<h2 id="parting-words">Parting words</h2>

<blockquote>
  <p>Let me just get this working and then I’ll see how to test it.</p>
</blockquote>

<p>Often times, we feel like testing code is of lower importance than source/implementation code. This way of thinking results in complex, unmaintainable code that is riddled with bugs. Spending time unpicking complex code structure for later testing takes longer than incrementally making decisions, ensuring they are easy to test and implement solutions to provided requirements.</p>

<p>Therefore, I encourage everyone to take the time to improve and hone their testing practices. You won’t be disappointed with the results.</p>

<p><strong>Happy coding, Gophers!❤️</strong></p>

<h3 id="resources">Resources</h3>

<p>Here are the links mentioned in the stream:</p>
<ul>
  <li>My <a href="https://bit.ly/3UFpweU">“Test-Driven Development in Go” book</a></li>
  <li>The <a href="https://bit.ly/3p2ZbeX">slides presented in this session</a></li>
  <li>The <a href="https://github.com/addetz/gophertale">repository with the demo code</a></li>
</ul>]]></content><author><name></name></author><category term="go" /><category term="go" /><category term="tdd" /><category term="code" /><summary type="html"><![CDATA[I recently had the pleasure of discussing and demonstrating some of the key concepts of my "Test-Driven Development in Go" book on a live stream. This post summarises the main points covered by this 1hr coding session. Understanding these testing essentials will go a long way to helping you become a TDD practitioner. Read on to see why you should care about testing and TDD!]]></summary></entry><entry><title type="html">The Future of Code Week: Will Languages like Go and Rust Overtake their Legacy?</title><link href="https://adelinasimion.dev/talks/foc-emerging/" rel="alternate" type="text/html" title="The Future of Code Week: Will Languages like Go and Rust Overtake their Legacy?" /><published>2022-11-14T00:00:00+00:00</published><updated>2022-11-14T00:00:00+00:00</updated><id>https://adelinasimion.dev/talks/foc-emerging</id><content type="html" xml:base="https://adelinasimion.dev/talks/foc-emerging/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        6 mins
    
  </p>
</div>

<p>In this post, I share some of my key thoughts from my LinkedIn Learning Future of Code Week episode discussing emerging languages. This session takes place on November 17th 2022. I was thrilled to be invited to share my thoughts with Marcus and Ray.</p>

<p><strong>Make sure to sign up to  <a href="https://bit.ly/foc-ep04" target="_blank">the event on LinkedIn!</a></strong></p>

<div class="container">
    <div class="row">
      <figure class="centered">
        <a href="https://bit.ly/foc-ep04" target="_blank">
                <img class="centered" src="/assets/foc_thumbnail.png" alt="Talk banner" />
            </a>
        </figure>
    </div>
</div>

<h2 id="session-summary">Session summary</h2>
<blockquote>
Emerging languages often try to change how developers solve problems, but they also often change the course of legacy languages. Programming languages like Go and Rust are not just inventing new ways to work with code, but also having a clear effect on new versions of existing languages. Will the new take over the old? Will the adjustments to existing programming languages be enough to stave innovation? Or, is it best at some point to start from scratch and rethink the foundation of how we approach programming?
</blockquote>

<h2 id="what-go-does-well">What Go does well</h2>
<p>Go has been hailed as a language that is <strong>easy to use and deploy</strong>. There are a few reasons that should be top of mind when discussing this:</p>
<ul>
  <li><strong>Small syntax</strong> - Go’s syntax has been made small by design, so that it’s easy to pick up and become productive with. One of the <a href="https://golang.org/doc/faq#creating_a_new_language" target="_blank">purposes of the Go project</a> was to simplify the act of programming and make it easier for developers to write statically typed code.</li>
  <li><strong>Static typing</strong> - Go code is strongly, statically typed and compiled. The compiler catches a variety of bugs and allows for certain compile time performance optimizations. Go has built-in types for slices &amp; maps which are easy to use.</li>
  <li><strong>Structs</strong> - Go isn’t technically <a href="https://golang.org/doc/faq#Is_Go_an_object-oriented_language" target="_blank">an object oriented language</a>, but custom types are created using the <code class="language-plaintext highlighter-rouge">struct</code> keyword. Structs can have methods attached to them in the same way objects do. They have been described as <em>lightweight objects</em> since they do not support type inheritance.</li>
  <li><strong>Interfaces</strong> - While Go doesn’t support type hierarchy, <code class="language-plaintext highlighter-rouge">interface</code> types create reusable behaviours in a versatile and robust way according to the principle of <a href="https://en.wikipedia.org/wiki/Composition_over_inheritance" target="_blank">composition over inheritance</a>. Interfaces are <em>implicitly implemented</em> on structs by the Go compiler. A struct can implement several interfaces just as long as it implements all the methods that they require. A common use case of interfaces is to wrap code coming from an external library into an interface on the side of <em>the calling code</em> and only expose a subset of external functionality in the internal codebase.<code class="language-plaintext highlighter-rouge">interface{}</code> is known as <em>the empty interface</em>. It is satisfied by all types and is used as a parameter type by code that handles values of unknown type.</li>
  <li><strong>Building and testing Go code</strong> - The <a href="https://golang.org/cmd/go/" target="_blank">go command</a> exposes functionality for building &amp; testing Go code. This is easy to use and comes with the default Go installation. The source code is built into a binary executable. Executables can be built for other targets/architectures using <em>cross compilation</em>.</li>
  <li><strong>Deploying Go code</strong> - The binary executable of Go source code contains not just application code, but also all the support code needed to execute the binary. This means that the Go executable can run without the need for system dependencies such as Go tooling to run on a new system, unlike other languages. Go executables can be <em>directly deployed</em>.</li>
  <li><strong>Generics</strong> - recently added to Go, generics allows us to write better libraries that and data structures. From my experience, adoption of generics in production has been cautious. The Go team have put together <a href="https://go.dev/blog/when-generics" target="_blank">talks and posts</a> which discuss when <em>not</em> to use generics, as they are not a silver bullet to better code.</li>
</ul>

<h2 id="performance--concurrency">Performance &amp; Concurrency</h2>
<p>Go is a <strong>fast and performant</strong> language due to some very important optimizations:</p>
<ul>
  <li><strong>Inlining</strong> - the Go compiler saves function calls by treating the body of a function as if it were part of the calling function. This has the trade off of increasing binary size, so Go only does so when it makes sense.</li>
  <li><strong>Escape analysis</strong> - Go implements this optimization which analyzes the scope of references to a value. If the references do not escape scope then they are saved on the <em>stack</em> which is much faster and does not need to be garbage collected.</li>
  <li><strong>Garbage collection</strong> - prevents memory leaks and has very low latency. The Go garbage collector is an intricate piece of code that you can check out on <a href="https://tip.golang.org/doc/gc-guide" target="_blank">the Go Blog</a>.</li>
  <li><strong>Concurrency</strong> - Goroutines are multiplexed to a small number of OS threads. They are described as <em>lightweight threads</em> with small stack sizes that are <em>cooperatively scheduled</em> and managed by the Go runtime. Goroutines yield control at natural stopping points, making them more performant than kernel managed threads.</li>
</ul>

<p>One of the big advantages of using Go is the <strong>easier and more intuitive model of concurrency</strong> that is central to the language:</p>
<ul>
  <li><strong>Goroutines</strong> - Functions/methods can be run concurrently to other functions/methods by starting a Goroutine using the <code class="language-plaintext highlighter-rouge">go</code> keyword. They allow our application to use its resources optimally and perform more than one piece of work. All of the complex management and scheduling of goroutines is abstracted from the developer. Built on the concept of coroutines that is also used in Kotlin.</li>
  <li><strong>Channels</strong> - Goroutines communicate through channels, which can be thought of as pipes through which data flows. Channels avoid data races by design as they maintain queues of goroutines and data themselves.The solid basics of Goroutines and channels can be combined to form a variety of basic and advanced concurrency patterns. Two notable concurrency patterns are <a href="https://blog.golang.org/pipelines" target="_blank">pipelines</a> and <a href="https://golangbot.com/buffered-channels-worker-pools/" target="_blank">worker pools</a>.</li>
</ul>

<h2 id="the-future-of-go">The future of Go</h2>
<p>In my opinion, the future of Go is bright ☀️:</p>
<ul>
  <li><strong>Replacing legacy services</strong> - due to its superior performance, engineering teams will continue to decompose monoliths and write new services in Go. In an increasing amount of companies, Go and microservices go together hand in hand. This de-facto choice is because Go’s
<a href="https://pkg.go.dev/net/http" target="_blank">net/http package</a> makes writing REST APIs easy.</li>
  <li><strong>Increased demand</strong> - Go has recently “become a teenager” with its 13th birthday. It usage has been increasing and I would argue that it is moving away from emerging language status, as it has become adopted by major tech companies for mission critical jobs. You can see <a href="https://go.dev/solutions/#case-studies" target="_blank">the full list of case studies on the Go blog</a>.</li>
  <li><strong>Compatibility promise</strong> - <a href="https://twitter.com/_rsc" target="_blank">Russ Cox</a> gave a <a href="https://youtu.be/v24wrd3RwGo" target="_blank">talk at GopherCon 2022</a> about Go’s compatibility promise, which I really recommend. When updating to a new version of Go, you must compile your code again, but the team ensure that new versions do not break existing code. These guarantees make Go suited for writing Go code for the long term.</li>
</ul>

<blockquote>
"Go is boring, and that's good!" - Russ Cox
</blockquote>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://youtu.be/v24wrd3RwGo" target="_blank">
                <img class="centered" src="/assets/boring_go.png" alt="GopherCon 2022: Russ Cox - Compatibility: How Go Programs Keep Working" />
            </a>
        </figure>
    </div>
</div>

<h2 id="parting-words">Parting words</h2>
<p>Obviously, I’m a huge Go lover ❤️ and I believe that the language is here to stay. It’s got so many cool features the Go team do a great job to improve tooling and add new features. An often underrated aspect is <strong>community</strong>. I’m proud to be part of the Go community, which is inclusive and welcoming. I think Gophers worldwide will continue to advocate for the language and grow.</p>

<p>Join the <a href="https://gophers.slack.com/" target="_blank">Gophers Slack</a>.</p>]]></content><author><name></name></author><category term="talks" /><category term="go" /><category term="talks" /><summary type="html"><![CDATA[In this post, I share some of my key thoughts from my LinkedIn Learning Future of Code Week episode discussing emerging languages. This session takes place on November 17th 2022. I was thrilled to be invited to share my thoughts with Marcus and Ray.]]></summary></entry><entry><title type="html">Nevertheless, Adelina coded</title><link href="https://adelinasimion.dev/jobs/she-coded/" rel="alternate" type="text/html" title="Nevertheless, Adelina coded" /><published>2022-03-03T00:00:00+00:00</published><updated>2022-03-03T00:00:00+00:00</updated><id>https://adelinasimion.dev/jobs/she-coded</id><content type="html" xml:base="https://adelinasimion.dev/jobs/she-coded/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        5 mins
    
  </p>
</div>

<p>In this post, I share some of my tech story as part of the <a href="https://dev.to/devteam/share-your-2022-shecoded-story-to-donate-20-to-closing-the-tech-gender-gap-2hid">Dev.to SheCoded campaign</a>, organised on the occasion of International Women’s Day 2022. I won’t be using names of individuals or companies in this retelling, but if you recognise yourself in the narrative, don’t reach out to me with an explanation or justification. Just DO BETTER THAN YOU’VE BEEN DOING!</p>

<p><strong>So, let’s begin.</strong></p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/Ymo8G7SGzk63YRqZai/giphy.gif" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/Ymo8G7SGzk63YRqZai/giphy.gif" alt="Do better" />
            </a>
        </figure>
    </div>
</div>

<h2 id="going-to-university">Going to university</h2>
<p>Being a woman does sometimes feels like drawing the short straw. Being an Eastern European woman on this wonderful continent 🇪🇺 sometimes feels like getting that already short straw broken in half. I am proud to be Romanian 🇷🇴 and I lived most of my life abroad, over two decades now. My family and I have lived through many prejudices for our accent, hair colour and “funny ways”.</p>

<p>Throughout my entire life, I have had the good fortune of having the support of my mother, father and older brother. They have been my compass, my strength and my unwavering supporters. ❤️</p>

<p>When I was 18, under the guidance of my family, I enrolled into the IT Engineering programme at the Technical University of Denmark in 2007. Yes, I did choose it because we thought it would be a lucrative career. When you are trying to make it in one of the most expensive places in Europe, you don’t have the luxury of discovering what your passion or dream job is.</p>

<h2 id="my-university-friends">My university “friends”</h2>
<p>I arrived at university wide eyed and excited. The first two years were absolutely brutal - writing code didn’t come naturally to me, the subject matter was terse and I had to put in a lot of hours of studying. 
However, my dilligence did eventually pay off and I started getting high marks.</p>

<p>My university colleagues and “friends” made many sexist and callous remarks. One person flat out accused me of sleeping with the 60 year old male professor, another accused me of getting the grade because of the outfit I wore. Finally, when we were assigned a female professor, I was accused of getting the grade because we were both women.</p>

<p>Some of my professors weren’t exactly stellar either. One of them told me that if I wore red nail polish again he would flunk me as he found it too “aggressive”… and while I was at it I should get rid of the makeup too!</p>

<p>All of this had long term repercussions on me in the form of feeling out of place and like an impostor for much of my career. I have no doubt I would have quit if I hadn’t had my family in my corner, but I graduated with a high GPA and held my head high when I received my diploma. 🎓</p>

<p>I wish I would have stood my ground when I was treated poorly, but most importantly, I wish the few people I was close to had stood up for me. I remember the silent faces alongside those who accused me in front of everyone. Don’t be a silent face in someone’s forever memory.</p>

<p><em>We must learn to be better allies for women in tech!</em></p>

<h2 id="the-missing-female-mentor">The missing female mentor</h2>
<p>After I finished my studies, I moved to London 🇬🇧 in 2014. I was fortunate to work with some great managers and engineers in my early career. They taught me technical fundamentals, supported me and helped me improve my self esteem.</p>

<p>After some time, I was excited to work for my first female manager. She ended up being really tough: she told me off for “being mousy and batting your eyelashes”, she forced us to deliver subpar work for tight deadlines and she would take out her bad days on the team. I have since worked with many accomplished, truly amazing women. 🤩</p>

<p>We often hold other women to the same prejudices that we have been held to our entire lives. I strive to be the female mentor I wasn’t able to find earlier in my career - to my friends, colleagues and anyone who reaches out to me.</p>

<p><em>As women in tech, we must be better role models and mentors for each other!</em></p>

<h2 id="dont-say-the-m-word">Don’t say the M word</h2>
<p>Early in my career, I was often told what the maternity benefits packages were. They were probably trying to bolster my perception of the benefits package. I dismissed them with the wave of a hand. What’s this information to me? I’m young.</p>

<p>As I approached my 30’s, I did become aware of my biological clock. The recruiters stopped mentioning their maternity packages. I became keenly aware that if I say the M word, <em>maternity</em>, it would be potentially offputting to prospective employers. So, I stayed silent and signed contracts without asking.</p>

<p>The UK has absolutely horrible <a href="https://www.gov.uk/maternity-pay-leave">maternity leave</a>, compared to many European countries. The law does not protect women’s income during maternity, so the private employer packages vary a lot here.</p>

<p>I will speak out and ask about maternity packages in the future. We have to get rid of the stigma of women in their 30s asking for their rights to decent maternity protections.</p>

<p><em>We need to support diversity in tech with generous maternity AND paternity packages!</em></p>

<h2 id="parting-words">Parting words</h2>
<p>Thanks for reading all about my tech story and thoughts! It means a lot to me that you cared enough to read it. ⭐️
All in all, I feel optimistic for the future. I do believe that things are improving, even though we are far from true gender equality. I will strive to be a positive force of change in tech.</p>

<p>I will leave you with some family wisdom (I’m actually not sure if this is Romanian expression, or if it’s just a thing my mother says 🙈). Whenever I was sad or felt things were not going my way, my mother would say “the horses don’t die when the dogs wish them to” (<em>nu mor caii cand vor câinii</em>).</p>

<p>The meaning of it is related to hunting. The horses and dogs take off in the hunting party. Obviously, horses have much more stamina than dogs. Naturally, the dogs tire first and exhaustedly wish the horses the worst, but they just keep running. 🐎 I suppose this is a roundabout way of saying <em>haters gonna hate</em> 😆, but I like thinking of horses instead. 🐴</p>

<p><em>Remember, you’re a majestic horse and you leave us all in your dust!</em></p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/ByTh8UTOcOXL2/giphy.gif" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/ByTh8UTOcOXL2/giphy.gif" alt="Running horses" />
            </a>
        </figure>
    </div>
</div>]]></content><author><name></name></author><category term="jobs" /><category term="SheCoded" /><category term="career" /><summary type="html"><![CDATA[In this post, I share some of my tech story as part of the Dev.to SheCoded campaign, organised on the occasion of International Women's Day 2022. I won't be using names of individuals or companies in this retelling, but if you recognise yourself in the narrative, don't reach out to me with an explanation or justification. Just DO BETTER THAN YOU'VE BEEN DOING!]]></summary></entry><entry><title type="html">Tips for your DevRel interview</title><link href="https://adelinasimion.dev/jobs/interview-devrel/" rel="alternate" type="text/html" title="Tips for your DevRel interview" /><published>2022-02-20T00:00:00+00:00</published><updated>2022-02-20T00:00:00+00:00</updated><id>https://adelinasimion.dev/jobs/interview-devrel</id><content type="html" xml:base="https://adelinasimion.dev/jobs/interview-devrel/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        3 mins
    
  </p>
</div>

<p>In this post, I share what I learned about interviewing for a DevRel role, as I think there are a lot of folks who think they can’t achieve this role. This short list of Dos and Don’ts are really simple and easy to address. Make sure you follow them so you don’t lose out on any great DevRel opportunities.</p>

<p><strong>Let’s make the most of those interviews!</strong></p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/AYECTMLNS4o67dCoeY/giphy-downsized-large.gif" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/AYECTMLNS4o67dCoeY/giphy-downsized-large.gif" alt="Job interview" />
            </a>
            <figcaption class="imgcap"><i>Let's make the most of those interviews!</i></figcaption>
        </figure>
    </div>
</div>

<h2 id="interview-tips">Interview tips</h2>
<ol>
  <li>You <strong>DON’T</strong> need to have a massive social media following to get your first DevRel role, but you <strong>DO</strong> need to have a Twitter, GitHub and LinkedIn profiles with some relevant posts on them.
    <ul>
      <li>As part of their initial screening, your future employer will look up your social media profile to see how you engage with the Tech community.</li>
      <li><a href="https://twitter.com/eddiejaoude">Eddie Jaoude</a> often explains on Twitter how to engage with others in a constructive and friendly way.</li>
    </ul>
  </li>
  <li>You <strong>DON’T</strong> need to have a huge portfolio of talks, but you <strong>DO</strong> need to have some current examples of material you could produce.
    <ul>
      <li>Start a blog or write on <a href="https://dev.to/">dev.to</a> or <a href="https://medium.com/">Medium</a> to produce some writing samples. Personally, I prefer <a href="https://dev.to/">dev.to</a> between the two as the text editing is in markdown.</li>
      <li>If you do manage to speak at a conference, then you can use this as a video sample content. Otherwise, try to record a short tutorial or similar and upload to Youtube.</li>
      <li>I made this blog <a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll">using Jekyll and Github Pages</a>, but if I were to start over I’d probably opt for <a href="https://dev.to/">dev.to</a>.</li>
      <li>In my experience in interview process, everyone looked at my blog and read some writing samples, including the CTO, when I got to the final round.</li>
    </ul>
  </li>
  <li><strong>DO</strong> write a bespoke resume that highlights your DevRel adjacent experience.
    <ul>
      <li>Engineers are often used to just sending round the same resume to all their roles, as it doesn’t really play that much of a role when getting selected for interviews. This is not the best tactic if looking to get your first DevRel role.</li>
      <li>I wrote up a special resume that highlighted my relevant experience more than just the technologies I worked with. You should include: your talk samples, your blog, any event organising experience (such as hackathons or other events) and any open source contributions you might have.</li>
      <li>This will help your future employer see your DevRel potential, even if you might not have full time DevRel experience.</li>
    </ul>
  </li>
  <li><strong>DON’T</strong> underestimate the power of the cover letter.
    <ul>
      <li>Engineers are not used to writing cover letters, but I think they are a great opportunity to showcase your writing skills when applying for a DevRel role.</li>
      <li>I wrote a 1 page cover letter, where I explained why I wanted to be considered for the role. This gave me the option to explain my resume a bit more and offered some background about why I was interested in working at the company I was applying to. Again, everyone read this letter throughout the interview process.</li>
    </ul>
  </li>
  <li><strong>DO</strong> research the company you are applying to more than you might do for an engineering role.
    <ul>
      <li>Most DevRel roles, including the ones where you will be joining an established DevRel team, require you to be a self starter with ideas.</li>
      <li>Make sure you research the company you are applying to and come up with some concrete ideas of how you can contribute to their program.</li>
      <li>I made some boards with screenshots from the company website where I jotted some ideas. In the end, I ended up sharing my boards during the interview. As I was quite nervous, my preparation helped me anchor myself and present my ideas.</li>
    </ul>
  </li>
</ol>

<h2 id="parting-words">Parting words</h2>
<p>It might be intimidating to move into a new role, such as DevRel, but don’t underestimate what you can bring to the table!<br />
The field of DevRel is still growing and getting more established, so there is definitely place for you to get started in it.</p>

<p>I’m happy to help with resume and cover letter reviews, so please don’t hesitate to reach out to me on <a href="https://twitter.com/classic_addetz">Twitter</a> if you need a second pair of eyes on these.</p>

<p><strong>Happy interviewing &amp; job hunting!</strong></p>]]></content><author><name></name></author><category term="jobs" /><category term="career" /><category term="interviews" /><summary type="html"><![CDATA[In this post, I share what I learned about interviewing for a DevRel role, as I think there are a lot of folks who think they can't achieve this role. This short list of Dos and Don'ts are really simple and easy to address. Make sure you follow them so you don't lose out on any great DevRel opportunities. Let's make the most of those interviews!]]></summary></entry><entry><title type="html">My 2021 nail art 💅</title><link href="https://adelinasimion.dev/hobbies/nails-year/" rel="alternate" type="text/html" title="My 2021 nail art 💅" /><published>2021-12-31T00:00:00+00:00</published><updated>2021-12-31T00:00:00+00:00</updated><id>https://adelinasimion.dev/hobbies/nails-year</id><content type="html" xml:base="https://adelinasimion.dev/hobbies/nails-year/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        5 mins
    
  </p>
</div>

<p>As 2021 comes to an end today, it’s important to take time to celebrate our wins and achievements throughout the year. I’m going to show you some of my nail designs that I’m most proud of.</p>

<p>You might wonder why bother putting effort into nails? They chip, break and they’re <em>just</em> nails. My answer is that I look at my hands all the live long day, so I want to look at a well presented manicure.</p>

<p>After all, isn’t it human nature to love things that aren’t fated to last? Youth, beauty, flowers… NFTs and Web3 😆
Also, it’s my blog and I’ll put nails on it if I want to 💅</p>

<p><strong>NOTE:</strong> Due to the <a href="https://www.annabellelouise.co.uk/the-nail-files-blog/item/10-do-acrylics-and-gel-polish-ruin-your-nails-the-truth">many dangers of improper gel use</a>, all my nail art is done with regular, wet polish on top of my natural nails. The techniques I describe here apply to this type of polish.</p>

<p><strong>Let me take you on my epic journey in nail art!</strong></p>

<h2 id="my-first-set-1️⃣">My first set 1️⃣</h2>
<p>My very first set was an absolute disaster. I had one single brush that my partner had given me and I <strong>very shakily</strong> drew on these uneven lines. Absolute horror show! 😱</p>

<p>Even though this set is <em>quite bad</em>, I did get my essentials right. I applied a nourishing base coat, two coats of base colour, the “nail art” and then sealed everything with topcoat. These steps are very important to a long lasting manicure.</p>

<p>I’m including this set so you can get an idea of how badly things can go. Also, in true <a href="https://www.britannica.com/science/Dunning-Kruger-effect">Dunning-Kruger</a> fashion, I actually thought they were <em>not that bad</em>.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/first_set.jpeg" alt="Terrible Nail art" />
        </figure>
    </div>
</div>

<h2 id="the-discovery-of-striping-tape-">The discovery of striping tape 💡</h2>
<p>After seeing how tough it is to draw straight even lines with your left hand on your right hand and YOLO’ing my first set, I looked up how lines are actually drawn. I discovered that colours are layered together and crisp lines are produced using striping tape - which is basically a very thin adhesive masking tape. It’s available all over the Internet.</p>

<p><em>Striping tape should only be applied on fully dry, top-coated nails!</em> See <a href="https://www.youtube.com/watch?v=VbZv5dCGGcw">this excellent video</a> if you want to learn how to use striping tape correctly.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/striping_tape.jpeg" alt="Striping tape nail art" />
        </figure>
    </div>
</div>

<h2 id="the-power-of-the-liner-brush-">The power of the liner brush ⌇</h2>
<p>While glitter polish is very forgiving to uneven applications, the liner brush has a long head that allows you to evenly load it and draw long lines. This is <a href="https://peacci.com/products/251-liner-brush-5060727563016.html">my liner brush</a>, but there are many others.</p>

<p>The liner brush is the hero 🦸🏻‍♀️ of evenly coloured lines, from beginning to end. The set below is made with a combination of striping tape and liner brush.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/liner_brush.jpeg" alt="Liner brush nail art" />
        </figure>
    </div>
</div>

<h2 id="cheating-a-steady-hand-with-tip-guides-️">Cheating a steady hand with tip guides ✍️</h2>
<p>Even with the miracle liner brush, I found it really difficult to apply long even lines on myself. You can buy <a href="https://www.amazon.co.uk/Packs-French-Manicure-Tip-Guides/dp/B004MXK9SO">tip guides</a> online to help you achieve the correct shape. As with striping tape, remember to apply them only on top of fully dry, top-coated nails otherwise the polish will rip off.</p>

<p>I really like this set, but I must admit it took me <strong>over 3 hours to do</strong> 🙈 It was really time consuming to pain stakingly align the chevron guides to match, so tip guides are kind of a pain.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/tip_guides.jpeg" alt="Tip guides nail art" />
        </figure>
    </div>
</div>

<h2 id="how-long-can-i-go-️">How long can I go? 🤷‍♀️</h2>
<p>This was the longest set of nails I had and they are absolutely fabolous!💯</p>

<p>They also demonstrate the almond nail shape, which comes naturally to my very curved nails. There are <a href="https://graziadaily.co.uk/beauty-hair/nails/nail-shapes-types/">7 nail shapes</a>, but I find the almond the easiest to shape on my nails with a nail file.</p>

<p>Nail health is very important if you want to go long. You should focus on you supplements(B12 and Biotin in particular), as well as get into the habit of applying <a href="https://www.healthline.com/health/cuticle-oil">cuticle oil</a>, which moisturizes and strengthens nails, if you want to grow naturally long nails. This is <a href="https://peacci.com/nail-polish/202-cuticle-oil-5060727561616.html">my cuticle oil</a>, but there are many others online.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/long_nails.jpeg" alt="Long nail art" />
        </figure>
    </div>
</div>

<h2 id="the-drama-of-a-good-ombre-">The drama of a good ombre 🎭</h2>
<p>I’ve never been a girl for understated nails, so I absolutely love a dramactic good ombre.❤️</p>

<p>The process is a bit messy and time consuming on wet polish - you apply the polish to a makeup sponge and then layer it on your nails. You can see this <a href="https://www.youtube.com/watch?v=hwlBobg0djc">excellent tutorial</a> if you’d like to make your own ombre.
I highly recommend using a <a href="https://moyou.co.uk/products/cuticle-guard-10-ml">liquid cuticle guard</a> (or at least sticky tape!) as the polish will go all over your hands and it will be a nightmare to clean up.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/ombre.jpeg" alt="Ombre nail art" />
        </figure>
    </div>
</div>

<h2 id="delicate-art-with-water-decals-">Delicate art with water decals 🌊</h2>
<p>My dear friend Alicia ❤️ gifted me some amazing water decals that can be used on nails. They are super cool and easy to use - you submerge the decal and the paper it’s attached to in water for 10 seconds and then you can delicately slide it off the paper and onto your nails.</p>

<p>Decals are really cheap and available all over the internet. They are a wonderful addition to a delicate manicure. You can see this <a href="https://www.youtube.com/watch?v=pPtLU17r-To">excellent video</a> if you want to see how to use them.</p>

<p><em>Water decals should only be topcoated once they are fully dry!</em> Otherwise, the topcoat will not seal properly and they will pop off.</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/water_decals.jpeg" alt="Water decals nail art" />
        </figure>
    </div>
</div>

<h2 id="finally-gold-flakes-for-the-new-year-️">Finally… gold flakes for the New Year! ⭐️</h2>
<p>Thanks for taking this journey in nail art with me! 🥳</p>

<p>It was really fun for me to share some of my favourite nails throughout the year. My sets last between 10 and 14 days so I did many more sets than those I’ve shared with you here. 🙈</p>

<p>My current set is a festive gold flakes set to welcome 2022! 🍾</p>
<div class="container">
    <div class="row">
        <figure class="centered">
            <img class="centered halfSize" src="/assets/nails/gold_flakes.jpeg" alt="Gold flakes nail art" />
        </figure>
    </div>
</div>

<h2 id="parting-words">Parting words</h2>
<p>I’ve learned a lot about this awesome new hobby this year. I’m always happy to exchange tips and tricks with anyone who wants to take it up, so don’t hesitate to <a href="https://twitter.com/classic_addetz">DM me on Twitter</a>.</p>

<p>A great place for nail art and ideas is <a href="https://www.reddit.com/r/lacqueristas/">r/lacqueristas</a>, where I sometimes post my sets.</p>

<p><strong>May 2022 bring you all strong nails and no chipped nail polish!</strong> ❤️ ❤️ ❤️</p>]]></content><author><name></name></author><category term="hobbies" /><category term="fun" /><summary type="html"><![CDATA[As 2021 comes to an end today, it's important to take time to celebrate our wins and achievements throughout the year. I'm going to show you some of my nail designs that I'm most proud of. You might wonder why bother putting effort into nails? They chip, break and they're just nails. My answer is that I look at my hands all the live long day, so I want to look at a well presented manicure. After all, isn't it human nature to love things that aren't fated to last? Youth, beauty, flowers... NFTs and Web3 😆 Also, it's my blog and I'll put nails on it if I want to 💅 Let me take you on my epic journey in nail art!]]></summary></entry><entry><title type="html">I’m going to be a Technology Evangelist! 🤩</title><link href="https://adelinasimion.dev/jobs/new-job-alert/" rel="alternate" type="text/html" title="I’m going to be a Technology Evangelist! 🤩" /><published>2021-09-04T00:00:00+00:00</published><updated>2021-09-04T00:00:00+00:00</updated><id>https://adelinasimion.dev/jobs/new-job-alert</id><content type="html" xml:base="https://adelinasimion.dev/jobs/new-job-alert/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        1 min
    
  </p>
</div>

<p>I’m super excited to share that I will be starting a new role as a Technology Evangelist at <a href="https://www.form3.tech/" target="_blank">Form3</a> starting Monday, September 6th! It’s such a dream come true to have this opportunity to pursue my passion and step into Developer Relations. In this post, I will share what this new move means to me.</p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/WUq1cg9K7uzHa/giphy-downsized-large.gif?cid=ecf05e474s3hbfpxbb2nga1fxp24jpqdeya4yu9dnjvmuotz&amp;rid=giphy-downsized-large.gif&amp;ct=g" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/WUq1cg9K7uzHa/giphy-downsized-large.gif?cid=ecf05e474s3hbfpxbb2nga1fxp24jpqdeya4yu9dnjvmuotz&amp;rid=giphy-downsized-large.gif&amp;ct=g" alt="Excited!" />
            </a>
        </figure>
    </div>
</div>

<h1 id="wait-what-is-a-technology-evangelist-">Wait, what is a Technology Evangelist? 🙈</h1>
<p>Evangelists are sometimes also known as <em>Technology Ambassadors</em>. In short, this role is all about representing a company and presenting its technical solutions to a variety of stakeholders.</p>

<p>The definition of this role varies, but to me, the technology evangelist role comprises of the following:</p>
<ul>
  <li>Working on internal and external technical documentation</li>
  <li>Helping produce marketing material which correctly represents the technology of their employer</li>
  <li>Speaking at conferences and blogging to promote their employer’s brand</li>
  <li>Helping with open source efforts to contribute to the tech community</li>
</ul>

<h1 id="the-only-way-is-up-">The only way is up! 🚀</h1>
<p>It’s been really nerve wracking making the decision to step away from my Back End role.
In the end, it all came down to passion and the good fortune of finding  an employer that wanted to invest in me. This encouraged me to take the leap! 🥳</p>

<p>For now, I am just super excited to have the opportunity to explore this role, speak at more conferences and really see what the developer relations life is all about. 🎤</p>

<p>Developer Relations roles and team are fluid and change from company to company and even over time. With this in mind, I think I’ll see the role very differently 6 months, a year from now. I just wanted to jot my thoughts down before starting this new, exciting journey.</p>

<p><strong>Cross your fingers for me as I take on this new challenge!🤞</strong></p>]]></content><author><name></name></author><category term="jobs" /><category term="career" /><summary type="html"><![CDATA[I'm super excited to share that I will be starting a new role as a Technology Evangelist at Form3 starting Monday, September 6th! It's such a dream come true to have this opportunity to pursue my passion and step into Developer Relations. In this post, I will share what this new move means to me.]]></summary></entry><entry><title type="html">Best Friends Forever(BFFs): Lambda and Go apps</title><link href="https://adelinasimion.dev/talks/lambda-bffs/" rel="alternate" type="text/html" title="Best Friends Forever(BFFs): Lambda and Go apps" /><published>2021-07-10T00:00:00+00:00</published><updated>2021-07-10T00:00:00+00:00</updated><id>https://adelinasimion.dev/talks/lambda-bffs</id><content type="html" xml:base="https://adelinasimion.dev/talks/lambda-bffs/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        5 mins
    
  </p>
</div>

<p>My talk for <a href="https://gophercon.eu/" target="_blank">GopherconEU 2021</a> is live on Youtube! Preparing for this conference has been such a wonderful learning experience. In this blog post, I will share some of my lessons learned about pitching, preparing and delivering my conference talk. I hope this will break down the process and encourage other newbie speakers  to take on this journey.</p>

<p><strong>Let’s get excited about public speaking!</strong></p>

<div class="video-container">
    <iframe src="https://www.youtube.com/embed/FJL7RXAIJzk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</div>

<h2 id="the-pitch">The Pitch</h2>
<p>Your pitch is your first and only chance to impress the conference organizers and convince them to choose your talk for their event. While some established conference speakers are invited to speak without pitching, most conferences will open a Call for Papers where anyone can pitch a talk. To keep things fair, organizers will then choose pitches from their Call for Papers without seeing the name and profile of the author.</p>

<p>The skeleton/structure I use for my pitches is:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># Talk title</span>
Insert your persuasive elevator pitch here
<span class="p">-</span> Choose a fun, but descriptive title for your talk
<span class="p">-</span> Include any technologies you intend to showcase
<span class="p">-</span> Describe the format of your talk ie live coding, demo app etc.

<span class="gu">## Overview</span>
Insert longer description of your talk here: 
<span class="p">-</span> Who is your intended audience? 
<span class="p">-</span> Why is it worth learning about your chosen topic? 
<span class="p">-</span> What is the angle you'll take on your topic? 

<span class="gu">## Structure</span>
Divide your talk into 3-4 rough sections
Describe each section in detail: 
<span class="p">-</span> What will you be introducing in this section? 
<span class="p">-</span> What will the audience take away from this section? 
<span class="p">-</span> How does it cohesively hang together with the previous/next section?
<span class="p">-</span> Include any rough points you intend to highlight

<span class="gu">## Conclusions</span>
Write a small paragraph describing exactly what we will learn from you
Keep the tone of this paragraph upbeat, encouraging people to attend your talk
</code></pre></div></div>

<p>You can see the entire pitch for my talk on <a href="https://www.papercall.io/talks/198726" target="_blank">PaperCall.io</a>.</p>

<h2 id="the-preparation">The Preparation</h2>
<p>Okay, you’ve been selected to speak! Fantastic.
Now it’s time to start preparing in good time to make sure that you are doing justice to yourself and your pitch.</p>

<p>Here are some helpful tips I’ve used during my conference preparation:</p>
<ul>
  <li><strong>Consider inviting a colleague to be your co-presenter</strong>: I really enjoy presenting as a duo since it allows me to incorporate fun exchanges with my colleague in front of the audience. This makes my talk more conversational and dynamic</li>
  <li><strong>Set deadlines for yourself</strong>: starting with the conference date, work backwards to set yourself deadlines. I recommend finishing your slides about a month before the conference and using the last month for rehearsing and polishing the content. You can still make changes in this last month, but aim for a complete first version about a month ahead of the conference date</li>
  <li><strong>Keep track of your work</strong>: treat your conference prep like any project and track your progress. Use any tool you like Trello, Miro, Jira, paper Post-Its, but make sure you keep track of your progress and any remaining tasks</li>
  <li><strong>Regularly check in with your colleagues</strong>: if you’ve opted to present alone, try to run your existing work by your colleagues as you create it. This will help you get ideas during the process but also keep you on track</li>
  <li><strong>Tell a coherent story</strong>: make sure that you ease into the more complicated/terse parts of your technical topic to ensure that members of the audience from different backgrounds can follow you. Make sure the sections of your presentation flow together and tell a  coherent story</li>
  <li><strong>Don’t underestimate the work</strong>: the rule of thumb for talks is that you should set aside 1 hour of preparation time for every 1 minute of finished talk ie. 30 hours of prep corresponds to 30 minutes of finished talk. If you are building a demo application, this will add even more preparation time</li>
</ul>

<h2 id="the-delivery">The Delivery</h2>
<p>As the talk approaches, it’s time to take this show on the road!!!</p>

<p>Here are some helpful tips I’ve used for my rehearsals:</p>
<ul>
  <li><strong>Rehearse by yourself</strong>: you should rehearse your talk end-to-end alone first. You might be tempted to stop if it doesn’t go well, but do a rough full run through first. This will give you an idea if you have too much or too little material to make sure you land the expected time length</li>
  <li><strong>Rehearse to your colleagues</strong>: after you have a good idea of roughly how long your talk will take, you can now ask some of your colleagues to listen to your talk. Aim for 2-3 dress rehearsals with your colleagues to make sure you have a good rhythm when the big day comes</li>
  <li><strong>Keep it conversational</strong>: conference talks shouldn’t be long, boring lectures. Make sure to keep your presentation style conversational and your language approachable. Plan what you’re going to say, but don’t be overly rehearsed</li>
  <li><strong>Always leave time for questions</strong>: time your talk to leave time for at least a few questions. While people in the audience can always come and discuss with you during breaks and socials, it is nice to discuss ideas with the audience as a whole, even if it is for a few minutes</li>
</ul>

<h2 id="parting-words">Parting words</h2>
<p>As I’ve discussed in this blog post, pitching and preparing a conference talk is a large undertaking and requires quite a bit of work.</p>

<p>But it’s not all doom and gloom!</p>

<p>Sharing your unique technical expertise and point of view with the community is a very rewarding experience. Preparing the talk teaches you lots of details about your chosen topic and public speaking itself is a great opportunity to challenge yourself in a whole new way. So if you’re curious about the experience, get pitching and just give it a go. I’m sure you won’t regret it.</p>

<p><strong>Happy conference speaking! Go be the star you are!</strong></p>]]></content><author><name></name></author><category term="talks" /><category term="go" /><category term="conferences" /><summary type="html"><![CDATA[My talk for GopherconEU 2021 is live on Youtube! Preparing for this conference has been such a wonderful learning experience. In this blog post, I will share some of my lessons learned about pitching, preparing and delivering my conference talk. I hope this will break down the process and encourage other newbie speakers to take on this journey. Let's get excited about public speaking!]]></summary></entry><entry><title type="html">Unit testing in Go</title><link href="https://adelinasimion.dev/go/testing-in-go/" rel="alternate" type="text/html" title="Unit testing in Go" /><published>2021-05-31T00:00:00+00:00</published><updated>2021-05-31T00:00:00+00:00</updated><id>https://adelinasimion.dev/go/testing-in-go</id><content type="html" xml:base="https://adelinasimion.dev/go/testing-in-go/"><![CDATA[<div class="reading-time">
  <p>
    Estimated reading time:
    
    
    
        6 mins
    
  </p>
</div>

<p>Unit testing is paramount to writing stable, production ready code. In this post, we will talk a bit about what unit tests should cover and table driven tests in Go.</p>

<p><strong>Let’s make Go tests our best friends!</strong></p>

<div class="container">
    <div class="row">
        <figure class="centered">
            <a href="https://media.giphy.com/media/WDn21GO1KmpNK/giphy.gif" target="_blank">
                <img class="fullSize" src="https://media.giphy.com/media/WDn21GO1KmpNK/giphy.gif" alt="Best friends" />
            </a>
        </figure>
    </div>
</div>

<h2 id="basics">Basics</h2>
<p>For the sake of this testing discussion, let’s say we have created a new <code class="language-plaintext highlighter-rouge">Calculator</code> that prints out formatted results and we want to ensure that it is working as expected.</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">Calculator</span> <span class="k">struct</span><span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">c</span> <span class="n">Calculator</span><span class="p">)</span> <span class="n">Add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="kt">int</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">if</span> <span class="n">y</span> <span class="o">&gt;</span> <span class="m">0</span> <span class="p">{</span>
		<span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"%d+%d=%d"</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"%d%d=%d"</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Go provides inbuilt support for testing using by using the <a href="https://golang.org/pkg/testing/" target="_blank">testing package</a>.
A test is created by writing a function with a name beginning with <code class="language-plaintext highlighter-rouge">Test</code> and being followed by the name of the method under test. The test signature takes exactly one parameter from the <code class="language-plaintext highlighter-rouge">testing</code> package as seen below.</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">TestAdd</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span>
</code></pre></div></div>

<p>The parameter <code class="language-plaintext highlighter-rouge">t</code> that is provided in the function signature is used to signal errors to the test runner by using <code class="language-plaintext highlighter-rouge">Fail</code> and <code class="language-plaintext highlighter-rouge">Errorf</code>. One simple test for our <code class="language-plaintext highlighter-rouge">Add</code> function can be:</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">TestAdd</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">want</span> <span class="o">:=</span> <span class="s">"2+3=5"</span>
    <span class="n">c</span> <span class="o">:=</span> <span class="n">Calculator</span><span class="p">()</span>
    <span class="n">got</span> <span class="o">:=</span> <span class="n">c</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="m">2</span><span class="p">,</span><span class="m">3</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">got</span> <span class="o">!=</span> <span class="n">want</span> <span class="p">{</span>
        <span class="n">t</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"Add(2,3) = %s; want %s"</span><span class="p">,</span> <span class="n">got</span><span class="p">,</span> <span class="n">want</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="the-unit-under-test">The unit under test</h2>
<p>Unit testing aims to test individual units or components of a piece of software. The purpose is to validate that each unit of the code performs as expected. In other words, unit tests are for verifying independent behaviours that we want to expose to outside of the component under test. Functions and structs are exported from Go <strong>packages</strong> so unit tests should verify the functionality that your packages expose.</p>

<p>In Go, tests live together with the source code in files that match the name of the source code file and ending in <code class="language-plaintext highlighter-rouge">_test</code>. While not enforced, Go also encourages tests to live in a separate <code class="language-plaintext highlighter-rouge">_test</code> package which has the dual purpose of making sure test functions do not leak into source code as well ensuring that only exported functions/behaviours are available in the test code. (<em>Note:</em> Go does not allow multiple packages to live in the same directory, but <code class="language-plaintext highlighter-rouge">_test</code> packages are exempt from this rule.)</p>

<p>The eagle eyed readers might have noticed that the packages in the <code class="language-plaintext highlighter-rouge">Calculator</code> example conveniently left out package names. We can now revisit this example and include our packages. The <code class="language-plaintext highlighter-rouge">Calculator</code> can now live in the <code class="language-plaintext highlighter-rouge">nice_math</code> package in a <code class="language-plaintext highlighter-rouge">calculator.go</code> file.</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">nice_math</span>

<span class="k">import</span> <span class="p">(</span>
    <span class="s">"fmt"</span>
<span class="p">)</span> 

<span class="k">type</span> <span class="n">Calculator</span> <span class="k">struct</span><span class="p">{}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">c</span> <span class="n">Calculator</span><span class="p">)</span> <span class="n">Add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="kt">int</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">if</span> <span class="n">y</span> <span class="o">&gt;</span> <span class="m">0</span> <span class="p">{</span>
		<span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"%d+%d=%d"</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"%d%d=%d"</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The test can live in the <code class="language-plaintext highlighter-rouge">nice_math_test</code> package in a <code class="language-plaintext highlighter-rouge">calculator_test.go</code> file. The test then imports anything it uses from the <code class="language-plaintext highlighter-rouge">nice_math</code> package explicitly.</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">nice_math_test</span>

<span class="k">import</span> <span class="p">(</span>
    <span class="s">"fmt"</span>
    <span class="s">"github.com/addetz/nice_math"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">TestAdd</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">want</span> <span class="o">:=</span> <span class="s">"2+3=5"</span>
    <span class="n">c</span> <span class="o">:=</span> <span class="n">nice_math</span><span class="o">.</span><span class="n">Calculator</span><span class="p">()</span>
    <span class="n">got</span> <span class="o">:=</span> <span class="n">c</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="m">2</span><span class="p">,</span><span class="m">3</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">got</span> <span class="o">!=</span> <span class="n">want</span> <span class="p">{</span>
        <span class="n">t</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"Add(2,3) = %s; want %s"</span><span class="p">,</span> <span class="n">got</span><span class="p">,</span> <span class="n">want</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="table-driven-tests">Table driven tests</h2>
<p><strong>Table driven tests</strong> have been growing in popularity amongst Go developers. This technique allows the same test setup to cover a variety of scenarios and ensure that the code is working as expected.</p>

<p>The outline of a table driven test is:</p>
<ul>
  <li>Declare a test case structure that holds inputs and expected outputs for the function. Optionally, a name for the test case can be stored as well in the structure as well</li>
  <li>Construct an list/map with the test cases we want to test. If using a map, the name of the function can be the map key. <em>Note:</em> I, personally, prefer to add the name of the test in the test case structure as it’s easier to understand conceptually than using the map key for the test name</li>
  <li>Range over the list/map of test cases and run any assertions necessary in a subtest using <code class="language-plaintext highlighter-rouge">t.Run</code></li>
</ul>

<p>We can now expand our previous test to cover all of the logic of our calculator <code class="language-plaintext highlighter-rouge">Add</code> method to test out those negative inputs that we had not looked at until now</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">nice_math_test</span>

<span class="k">import</span> <span class="p">(</span>
    <span class="s">"fmt"</span>
    <span class="s">"github.com/addetz/nice_math"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">TestAdd</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">tests</span> <span class="o">:=</span> <span class="p">[]</span><span class="k">struct</span> <span class="p">{</span>
		<span class="n">name</span> <span class="kt">string</span>
		<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="kt">int</span>
		<span class="n">want</span> <span class="kt">string</span>
	<span class="p">}{</span>
		<span class="p">{</span><span class="n">name</span><span class="o">:</span> <span class="s">"two positives"</span><span class="p">,</span> <span class="n">x</span><span class="o">:</span> <span class="m">1</span><span class="p">,</span> <span class="n">y</span><span class="o">:</span> <span class="m">2</span><span class="p">,</span> <span class="n">want</span><span class="o">:</span> <span class="s">"1+2=3"</span><span class="p">},</span>
		<span class="p">{</span><span class="n">name</span><span class="o">:</span> <span class="s">"one positive one negative"</span><span class="p">,</span> <span class="n">x</span><span class="o">:</span> <span class="m">1</span><span class="p">,</span> <span class="n">y</span><span class="o">:</span> <span class="o">-</span><span class="m">2</span><span class="p">,</span> <span class="n">want</span><span class="o">:</span> <span class="s">"1-2=-1"</span><span class="p">},</span>		
		<span class="p">{</span><span class="n">name</span><span class="o">:</span> <span class="s">"two negatives"</span><span class="p">,</span> <span class="n">x</span><span class="o">:</span> <span class="o">-</span><span class="m">1</span><span class="p">,</span> <span class="n">y</span><span class="o">:</span> <span class="o">-</span><span class="m">2</span><span class="p">,</span> <span class="n">want</span><span class="o">:</span> <span class="s">"-1-2=-3"</span><span class="p">},</span>
	<span class="p">}</span>
	<span class="n">c</span> <span class="o">:=</span> <span class="n">nice_math</span><span class="o">.</span><span class="n">Calculator</span><span class="p">{}</span>

	<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">tc</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">tests</span> <span class="p">{</span>
		<span class="n">t</span><span class="o">.</span><span class="n">Run</span><span class="p">(</span><span class="n">tc</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="k">func</span><span class="p">(</span><span class="n">t</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">got</span> <span class="o">:=</span> <span class="n">c</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="n">tc</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">tc</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
			<span class="k">if</span> <span class="n">got</span> <span class="o">!=</span> <span class="n">tc</span><span class="o">.</span><span class="n">want</span> <span class="p">{</span>
				<span class="n">t</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"got %s, want %s"</span><span class="p">,</span> <span class="n">got</span><span class="p">,</span> <span class="n">tc</span><span class="o">.</span><span class="n">want</span><span class="p">)</span>
			<span class="p">}</span>
		<span class="p">})</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Subtests allow an itemised view of each test and their outcome, making it easy to detect and fix failures.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>=== RUN   TestAdd
=== RUN   TestAdd/two_positives
=== RUN   TestAdd/one_positive_one_negative
=== RUN   TestAdd/two_negatives
--- PASS: TestAdd (0.00s)
    --- PASS: TestAdd/two_positives (0.00s)
    --- PASS: TestAdd/one_positive_one_negative (0.00s)
    --- PASS: TestAdd/two_negatives (0.00s)
PASS

All tests passed.
</code></pre></div></div>

<h2 id="assertions-and-libraries">Assertions and libraries</h2>
<p>When it comes to testing, there are a few libraries that are worth mentioning:</p>
<ul>
  <li>The <a href="https://golang.org/pkg/testing/" target="_blank">testing package</a> comes with the standard library. It is easy to start with, but it quickly becomes tedious and repetitive when used on more complex code. It also provides the ability to write benchmarks for our functions as well</li>
  <li>The <a href="https://github.com/stretchr/testify" target="_blank">testify library</a> provides easy to use assertions which come in super handy when asserting on objects. It also provides mocks for substituting dependencies (I’ve not really talked about mocks in this little post, as they deserve their very own discussion)</li>
  <li>The <a href="https://github.com/onsi/ginkgo" target="_blank">ginkgo library</a> provides BDD style tests using the given/when/then pattern and is usually used with the <a href="https://github.com/onsi/gomega" target="_blank">gomega matcher library</a></li>
</ul>

<h2 id="parting-words">Parting words</h2>
<p>Unit testing in Go is easy when making use of table driven tests to test the behaviours that your Go packages export. The <code class="language-plaintext highlighter-rouge">testing</code> package allows us to write subtests and write assertions for our code, allowing one test to cover multiple scenarios, while keeping traceability in test results.</p>

<p>Other libraries such as <code class="language-plaintext highlighter-rouge">testify</code> and <code class="language-plaintext highlighter-rouge">ginkgo</code> provide synctactic sugar on top of the standard testing package, but many voices in the Go community promote writing simple functions and tests, for which the <code class="language-plaintext highlighter-rouge">testing</code> package should be sufficient.</p>

<p>I frequently use the <code class="language-plaintext highlighter-rouge">testify</code> library for its assertions and mocks, but the structure of your tests and what they cover is more important than the library you choose for testing. I would definitely recommend starting out with just the standard testing library, keeping things simple for as long as possible and then moving to other alternatives as the need arises.</p>

<p><strong>Happy Go coding!</strong></p>]]></content><author><name></name></author><category term="go" /><category term="go" /><category term="code" /><summary type="html"><![CDATA[Unit testing is paramount to writing stable, production ready code. In this post, we will talk a bit about what unit tests should cover and table driven tests in Go. Let's make Go tests our best friends!]]></summary></entry></feed>