Category

Engineering

  • Engineering

    How I got into web development

    I fell into web development, that's how it feels without digging into the details. That does not sound like how you want to go about choosing a career but in reality, it was years of small decisions and nudges that I ended up doing work I really enjoy.

    I grew up enjoying all things computers, but let's be honest it was mostly video games. In high school, I took all of the subjects available that had anything to do with computing, except for the software development subject ironically. I think because I didn't know about the potential creative side, I thought it was all hard maths. There was a subject I did where my major project was a batman flash animation, I was motivated in that class -- while others might have been bludging off and playing flash games, I was focused on making my flash animation and enjoying every minute of it.

    Then it came time to do something after high school. I still didn't have a good idea of what I wanted to do so I choose a broad degree that involved computers — Information Technology at UOW. It was a mandatory programming subject in that degree that gave me a taste of software development, it involved building programs where the output was just in the terminal which didn't excite me much.

    Then came a subject that everything started clicking together, Web Programming -- I think it was called. It combined design and code, used some newer web technologies, and was taught by lecturers who were clearly passionate about the web. We did projects like redesigning the movies page and I loved it. It also gave me a taste of making something that was useful, other programming subjects I did previously were just about outputting lines to the console.

    Sam's first web project

    After this experience it still didn't occur to me that I could get a job doing this, I didn't know anyone that was doing web development as a job. So after university, I went on a month-long holiday and tried not to think about what I was going to do when I got back.

    When I got back I started applying for jobs, and a few of them for this role called frontend developer which was a new term to me. It was in the process of doing the take-home projects that I was given as part of the interview processes that I realised I could get a job in this thing I enjoyed.

    It's been around 5 years since then and time has gone fast. In that time I was thrown into the deep end of many projects and have always finished them with more knowledge than when I started. Thanks to both the talented people that I have worked with and the challenge of the projects themselves.

    I'm looking forward to the next chapter here at Easy Agile!

  • Engineering

    Foo Bar Nah

    Or why you should give meaningful names to example variables

    I bent over my desk in frustration, suppressing the urge to scream so as not to upset the rhythmic clack-clack of my coworkers. I’d been frustrated all morning by a particularly nasty React infinite re-rendering issue that I just couldn’t get working. The urge to scream came when, my own toolbox exhausted, I turned to Google.

    You see, it looked like someone else had come across the same issue and had decided to record a solution for prosperity (and internet points). I eagerly scanned the page for the sample code that would save my morning. Finding it, my eyes were drawn to the dreaded fooBarBaz and I knew my morning was about to get a whole lot worse before it got better.

    I actually love the history of programming and the little easter eggs fellow developers have passed down (my personal favourite - I am a teapot). These help to make this job interfacing with computers much more fun and human. I can appreciate that the practice of using fooBarBaz in naming example functions and variables has a long and storied tradition dating back at least to the Tech Model Railroad Club at MIT circa 1960. I acknowledge that the use of fooBarBaz is primarily not to introduce any distractions from the point which is being demonstrated. I also think that we should pretty much stop using them.

    I am always awed by the amount of information my fellow developers have left out there for me on the internet. So many people in this field seem to have an innate need to help others, leading them to put in countless hours to fill Stack Overflow and blogs with useful information. I can only imagine that the people putting in their time and effort to this end are hoping that their efforts will help as many people as possible. fooBarBaz gets in the way of that.

    Let me take off my developer hat for a second and put on my recently discarded, slightly misshapen and battered psychologist one. Interweaving complex facts into stories is a time tested technique which facilitates learning. Here in Australia, the technique has been used for tens of thousands of years by the Aboriginal and Torres Strait Islander peoples to help them to remember important and complex information such as the locations of waterholes across vast tracts of inhospitable desert. Our brains are networks of interconnected neurons so we are more likely to hold on to what we have learned when we are able to integrate new information into our current knowledge base. The modern term for this is associative learning.

    Additionally, as I’m sure you’ll remember from school, keeping learning interesting has been demonstrated to be a powerful motivator which energises learning.

    When we take all this time and effort to communicate with our fellow developers we can and should harness the advantage of associative learning and intrinsic motivation to make sure that the information we are putting out there is as useful as possible to as many people as possible. To this end I believe that we should give as much thought to meaningful naming when creating example code as we do in our own codebases.

    Marijn Haverbeke’s Eloquent Javascript regularly comes at the top of lists of books you should read when learning Javascript (JS). It is no coincidence that he is also a master at using meaningful names to help people to better understand coding principles. When teaching new programmers about string comparison in JS he uses the following example:

    console.log("Itchy" != "Scratchy"); // → true

    Marijn piggybacks off our existing knowledge about Springfield’s favourite cartoon characters to give extra meaning and interest to this example. We know that Itchy and Scratchy are a mouse and cat respectively and so most definitely not the same.

    Consider the same example but rendered with the dreaded Foo/Bar instead:

    console.log("Foo" != "Bar"); // → true

    To seasoned developers, this might be easy enough to parse: you’ve read hundreds of examples like this and so have learned the association between Foo and Bar and internalised it. But this creates a barrier for learning for new developers who have not yet internalised this rule and instead increases the mental load for them to understand the concept. It also misses out on creating that little spark of interest or joy to help pique the reader's interest and so increase their motivation to understand the underlying concept.

    I am not saying there is absolutely no place for fooBarBaz (although I think their utility is limited). The best way to use these terms is to emphasise that anything could be put in a certain place. An example of this is when we’re talking about arguments and parameters in JS functions. You see, there is no type checking in vanilla JS and so if we have a function like the following that takes a parameter and simply logs its value to the console, it doesn’t matter what type of argument we pass in:

    const consoleLogParameter = (foo) => {   console.log(foo); };  const bar = “bar”; const baz = 42;  consoleLogParameter(bar); // → “bar”;  consoleLogParameter(baz); // → 42;

    I believe that these terms have the most utility in this case as their purpose is to emphasise that their type doesn’t matter. I would also add the caveat to this that using these terms in this way is only suitable when you are producing content for experienced developers who are going to have built a working understanding of these terms.

    Even if this is aimed at experienced developers, I still believe that more meaningful names would be better in this example:

    const consoleLogParameter = (anyTypeOfData) => {   console.log(anyTypeOfData); };  const name = “Homer Simpson”; const age = 39;  consoleLogParameter(name); // → “Homer Simpson”;  consoleLogParameter(age); // → 39;

    Another example where more meaningful variable names would be useful is in relation to metasyntactic variables. These variables are commonly found in source code and are intended to be modified or substituted before real-world usage. Whilst these variables are only placeholders, I believe that it is also better to use a variable name which offers more context to your developer comrade to assist them when they are reading and implementing the code in future.

    We work in a wonderful profession with a rich history, where many people are willing to donate their time to helping to educate and mentor their fellow programmers. Using meaningful variable names in place of fooBarBaz is one way that we can ensure that this effort is worthwhile and helps as many people as possible. It lowers the barriers to entry for the profession, helping to create a more diverse and welcoming programming community.

    So ditch the fooBarBaz (but not the Teapot) and go forth and spark joy!

  • Engineering

    4 hacks for writing frontend tests 10x faster (probably!)

    We all know writing unit tests is important but sometimes it feels like it can take up more time than the feature work itself. I’ve found a couple of handy hacks that I feel have increased my speed when writing tests whilst also improving their quality and, being the kind fellow I am, I’m going to share those with you:

    Hack 1: Use Testing Playground

    I guess the first tip in this article is - use Testing Library. I didn’t make this its own point because it is already so popular. But if you are not using it yet, make sure you do!

    Unit testing with Testing Library is really easy and intuitive. Despite this, it can still be challenging to find the right queries or to understand why an element isn't being matched.

    Enter Testing Playground.

    Testing Playground allows you to render a component in a sandbox providing you with direct visual feedback of the component. It also allows you to interact with the rendered component to come up with the best queries to select elements. And, like Testing Library, everything it does is with accessibility (a11y) in front of mind so it teaches you about the importance of a11y and best practices while you use it.

    There are many ways you can use Testing Playground including a chrome extension and a browser based app.

    The best way I have found which has been an absolute time saver for me though is by invoking screen.logTestingPlaygroundURL() right from the test block itself. I usually find myself doing this as soon as I get the component rendering, just to get the lay of the land and work out what parts of it my test might like to interact with.

    Hack 2: Use test.todo

    Please don’t jump down my throat, but I have tried Test Driven Development and didn’t like it. Like anarchism, I think it sounds awesome in theory, but found that it actually slowed down my development cycle when I tried to implement it.

    I still like the idea of getting some thinking about testing down before I finish building a feature though and have settled on a process that, for me, seems to work well and keep my development moving along.

    I now use Jest’s test.todo to record what I am going to test as I am planning to and building out a feature (Big thanks to Karl for first introducing me to the idea!).

    My usual process goes a bit like this. First I capture the requirements spelled out for me by my awesome Product Owner (Hi Biz!) in test.todo form, like a todo list. Then, as I am building and encounter other edge cases and important testing areas I add these as test.todo’s too. That way, when it comes to testing time, I have thought through a lot of what I am going to test and am less likely to miss testing edge cases or important functional requirements.

    A simple example for a test.todo for the following <UserDetails /> component:

    import React from "react";export interface User {  firstName: string;  lastName: string;  username: string;  emailAddress: string;  SEN: string;}export interface ShowHideUserDetailsProps {  showDetails: boolean;  user: User;}const UserDetails = ({ showDetails, user }: ShowHideUserDetailsProps) => (  <>    {showDetails ? (      <div>        <h1>User Details</h1>        <ul>          <li>{user.firstName}</li>          <li>{user.lastName}</li>          <li>{user.username}</li>          <li>{user.emailAddress}</li>          <li>{user.SEN}</li>        </ul>      </div>    ) : (      <div>        <h1>Privacy Protected</h1>      </div>    )}  </>);export default UserDetails;

    Might be as follows:

    describe('<UserDetails />', () => {  test.todo('Should show user details when show details is true');  test.todo('Should NOT show user details when show details is false');});

    Hack 3: Use builder functions

    I used to find myself creating objects for each test to mock out values for testing. Then I wrote another component which used the same object and mocked it out again there. There’s got to be a better way, I thought. And Matt Smith at FinoComp introduced me to one.

    I now use builder functions which return commonly used object types in testing and which allow properties to be overridden everywhere. There is certainly a little bit of extra time needed to set them up but I find that, once they are done, the next time you have to interact with that object you are so glad they are there.

    // Example typeinterface User {  firstName: string;  lastName: string;  username: string;  emailAddress: string;  SEN: string;}interface ShowHideUserDetailsProps {  showDetails: boolean;  user: User;}// Builder pattern to build a mock object for the// ShowHideUserDetailsProps typeexport const buildShowHideUserDetailsProps = (overrides?: Partial<ShowHideUserDetailsProps>): ShowHideUserDetailsProps => {  const defaultShowHideUserDetailsProps = {    showDetails: false,    user: {      firstName: "Jazmyne",      lastName: "Jacobs",      username: "Kylee_Skiles37",      emailAddress: "Rashawn13@gmail.com",      SEN: "SEN-123456"    }  };  return { ...defaultShowHideUserDetailsProps, ...overrides };};

    There are some limitations to this pattern however as they become less useful with deeply nested object types. Additionally, they do require some upkeep when object types change in the codebase which brings me to my next point...

    Hack 4: Use a tool to mock your Typescript types

    Look, I’m going to be straight here. This is the part where I plug my own work but at least I left it for last, right?

    Whenever I found myself creating another mock object for testing I kept looking at my Typescript types and thinking, can’t something look at that and do it for me? This sent me down a search for a solution and I was so stoked to find intermock which is a command line tool that does just that. While it is still a work in progress and has some limitations I have found it super helpful when writing tests.

    I did find using the combination of the CLI and copy/pasting from the terminal a little cumbersome though. How could I make this even easier I thought.

    Enter my VSCode extension, Emulative. Simply select your type name, run a command through the Command Palette in VSCode and you can use Emulative to produce Typescript objects, Json objects or the aforementioned builder functions from Typescript types. These are automatically copied to the clipboard but the plain objects can also be sent to a new scratch file.

    GIF showing Emulative VsCode plugin creating mock objects

    But wait, there’s more! Where I work at Easy Agile we have a bunch of properties we work with from Jira which aren’t accurately represented by string or number. With Emulative you can set up key/value pairs which will overwrite any matching properties which are found in your types.

    Shout out to Easy Agile for giving me the time, resources and encouragement during an Inception Week to work on Emulative!

    Well, that’s it for me, I hope you find some of these tips and tricks useful for speeding up front end testing.

    Either way please feel free to sound off in the comments about nifty tricks you have found to improve your unit testing speed (or just how wrong I am about TDD).