<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kevin Lamping</title>
    <description>The latest articles on Forem by Kevin Lamping (@klamping).</description>
    <link>https://forem.com/klamping</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32007%2Fe8d792cc-921f-4e2a-979c-e2060360c382.jpeg</url>
      <title>Forem: Kevin Lamping</title>
      <link>https://forem.com/klamping</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/klamping"/>
    <language>en</language>
    <item>
      <title>Not All Tests Are Equal</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Tue, 20 Oct 2020 17:50:51 +0000</pubDate>
      <link>https://forem.com/klamping/not-all-tests-are-equal-ai7</link>
      <guid>https://forem.com/klamping/not-all-tests-are-equal-ai7</guid>
      <description>&lt;p&gt;Not all tests are equal. Some hold much more value than others.&lt;/p&gt;

&lt;p&gt;While all tests either give you a green checkmark or not, they value of that green checkmark can vary drastically.&lt;/p&gt;

&lt;p&gt;It's nice to see a green checkmark on the "About Us" page test letting you know that the page title is correct, but that test won't save the business thousands of dollars.&lt;/p&gt;

&lt;p&gt;However, seeing a red X on a test for the 'Get a Quote' page, the one that brings in a significant percentage of the businesses customers and is always forgotten about in testing, now that's a valuable test.&lt;/p&gt;

&lt;p&gt;You can't put a specific number on the value of any given test, but, thinking about it mathmatically, I would measure it with the following formula:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Value of functionality to the business x (chance that functionality will break + chance a bug won't be caught before release)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a bit of a formula, so maybe some examples will help demonstrate how it plays out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking at the Login
&lt;/h2&gt;

&lt;p&gt;First, let's think about login functionality. The login flow has a very high value to the business, but it also isn't likely that it will break. This is because it's not the most complex functionality and coding patterns are well established for login flows. To add on to that, if the login page is broken, there's a huge chance that it's caught outside of any automated tests, as normal usage will quickly reveal the bug.&lt;/p&gt;

&lt;p&gt;So while the value of the functionality is high, the value of a test for that functionality is low. The left side of the equation is a big number, but the right side is miniscule.&lt;/p&gt;

&lt;p&gt;Here's a very rough estimate of what the values for my equation would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Value to business: 100&lt;/li&gt;
&lt;li&gt;Chance it will break: 1%&lt;/li&gt;
&lt;li&gt;Chance it won't be caught: 1%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plugging that into the formula, you get: &lt;code&gt;100 x (.01 + .01) = 2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So you see, despite the large value to the business, the value of the test is much much smaller. This doesn't mean login tests aren't helpful, but just that compared to other tests, they aren't as valuable. &lt;/p&gt;

&lt;h2&gt;
  
  
  Registration Woes
&lt;/h2&gt;

&lt;p&gt;Now let's look at the registration flow. It's similar to the login flow, and is also of high value to the business (it's how you get new users). But, like the login page, registration flows are pretty unlikely to break due to the limited complexity of them, along with the fact that registration functionality isn't anything new.&lt;/p&gt;

&lt;p&gt;However, unlike th e login page, the registration flow isn't as "high-touch". It's not normal for developers and product owners to be manually using this flow, as they already have their accounts created. So, here are what my numbers would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Value to business: 80&lt;/li&gt;
&lt;li&gt;Chance it will break: 1%&lt;/li&gt;
&lt;li&gt;Chance it won't be caught: 20%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, plugging that into the formula, you get: &lt;code&gt;80 x (.01 + .2) = 16.8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So while the value is less than that of the login flow, because the flow is less used, the value of automation is much higher. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Else Won't be Caught?
&lt;/h2&gt;

&lt;p&gt;Hopefully by now I've demonstrated how my equation works. It's not a perfect equation, and I'm making up these numbers, so take it all with a grain of salt.&lt;/p&gt;

&lt;p&gt;That said, here are some examples where that "chance it won't be caught" part really plays a big role:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time of day issues (Trying to place a food order after restaurant is closed)&lt;/li&gt;
&lt;li&gt;Edge cases (Users with specific data outside normal usage)&lt;/li&gt;
&lt;li&gt;Calendar issues (Does functionality change between calendar years?)&lt;/li&gt;
&lt;li&gt;Network issues (How does the offline experience work?)&lt;/li&gt;
&lt;li&gt;Special Offers (Coupons, promotions, referals)&lt;/li&gt;
&lt;li&gt;A/B testing (Do specific users get a different experience from majority?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's plenty more to list, so let me know in the comments what you think should go there!&lt;/p&gt;

&lt;h2&gt;
  
  
  What Else is Likely to Break?
&lt;/h2&gt;

&lt;p&gt;For this part, I'm going to point you to the post "&lt;a href="https://dev.to/walrusai/the-five-most-common-bugs-you-should-be-writing-tests-for-11p2"&gt;The Five Most Common Bugs you Should be Writing Tests for&lt;/a&gt;", as it covers this subject well. But again, mention in the comments anything you find particularly prone to problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just Think About It
&lt;/h2&gt;

&lt;p&gt;To wrap things up, I just think that it's too easy to write tests without any specific reason or evaluation to whether they're useful or not. It's also easy to get wrapped up in trying to invent some magical way to test something, when in reality the value of that test just isn't worth the effort.&lt;/p&gt;

&lt;p&gt;So take some time to plan out why you're testing what your testing. The benefit of this won't be immediate, but in the long run, you'll be much more likely to catch bugs using your automation, which will make the product owners and business very happy, leading to much more support for your efforts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Header Photo by &lt;a href="https://unsplash.com/@tingeyinjurylawfirm?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tingey Injury Law Firm&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/scale?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>UI Test Automation Is an Awful, Wonderful Thing</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Fri, 08 May 2020 19:44:37 +0000</pubDate>
      <link>https://forem.com/klamping/ui-test-automation-is-an-awful-wonderful-thing-429o</link>
      <guid>https://forem.com/klamping/ui-test-automation-is-an-awful-wonderful-thing-429o</guid>
      <description>&lt;p&gt;I've spent many years in the test automation world and there's one thing that sticks out to me: It's a wonderfully terrible thing.&lt;/p&gt;

&lt;p&gt;It's wonderful in that it solves a very important need. Good automation can save immense amounts of time over the long run and catch bugs that would have made it to production.&lt;/p&gt;

&lt;p&gt;It's terrible in that it gets used in the wrong ways, done for the very questionable reasons, and poor implementations can be a real maintainability nightmare.&lt;/p&gt;

&lt;p&gt;But before I get to that, let's step back...&lt;/p&gt;

&lt;h2&gt;
  
  
  What is User Interface (UI) Test Automation?
&lt;/h2&gt;

&lt;p&gt;Truthfully, test automation is a lot of things. There are a multitude of programs and tools surrounding it, not to mention the various ideologies about automated testing in general (e.g., Test-driven Development vs. Behavior-driven Development). &lt;/p&gt;

&lt;p&gt;Aside from that, there are also different types of tests. Here, we're focusing solely on UI automation, but there's also unit, integration, performance, accessibility, usability, you-name-it testing.&lt;/p&gt;

&lt;p&gt;All of these are important to know about, and can provide as much or more value than UI testing. So why focus on UI testing?&lt;/p&gt;

&lt;p&gt;Well, you don't really have an option. You can't skip accessibility testing if you want to have a site that's accessible. Equally, you can't skip UI testing if you want to have a site that's not broken.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uyzwf5Rc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ul4y3ubjuxkvi0b2rkyk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uyzwf5Rc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ul4y3ubjuxkvi0b2rkyk.jpg" alt="A Robot at a Piano"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Truthfully, we're doing tons of UI testing. Every time someone loads up a website, they're testing the UI. When they click that button, does it make that thing happen? When I use my mobile device, does the site fit on my small screen?&lt;/p&gt;

&lt;p&gt;If you have a site in production, every user is testing your UI. Hopefully for them (and you), they're not the first ones to try it out.&lt;/p&gt;

&lt;p&gt;UI testing is constantly being done, just in a very labor-intensive way. Front-end developers working on the code will spend half of their day in the browser manually testing if their changes worked. If they're testing in an older browser, it will be 3/4ths of their day.&lt;/p&gt;

&lt;p&gt;UI testing is the simple (hah) task of validating that the code written for the browser, actually works in that browser, along with all the other components that went into that webpage.&lt;/p&gt;

&lt;p&gt;UI test automation is a way to convert those manual mouse clicks and keystrokes into coded scripts that we can run on a regular basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Talk Benefits
&lt;/h3&gt;

&lt;p&gt;I've alluded to this before, but it's worth repeating. Here are some of the many real-world benefits of automated UI testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jamie, your ace front-end developer, just finished their latest task and is itching to release it. While they were careful to validate that the new functionality works, unfortunately they forgot to test whether that new code broke the zip code widget on the contact page. Lucky for you, the UI automation test caught the error, and a fix was in place before the end of the day.&lt;/li&gt;
&lt;li&gt;Taylor is an awesome full-stack developer. They've got everything about their coding environment fine-tuned so that they can focus solely on pumping out fixes and new features... except for one thing: Taylor always forgets to check their code on slower, outdated computers. That's okay though, as our UI tests are configured to run on a variety of setups, and it just so happens that it caught that issue when running inside a Windows 8 environment.&lt;/li&gt;
&lt;li&gt;Casey is a great product manager, but sometimes forgets to clarify the small details. This means developers can make the wrong assumption during development, which is only discovered by Casey during product demos. By adding automated tests to the mix, developers and product managers are pushed to have regular conversations on the desired behavior of certain functionality, resulting in fewer surprises later on. &lt;/li&gt;
&lt;li&gt;Avery is a superb QA tester. With great attention to detail, Avery always thinks of unique ways in which the website would be seen. Unfortunately, manually testing these edge cases takes a fair amount of time to get in place. By adding automated scripts, Avery is able to programmatically generate the needed data for their tests, and allow them to run these scripts on a regular basis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are just a few ways test automation can help. I skipped over many other benefits for the sake of time, but there's one I omitted on purpose. Many folks claim that UI tests allow you to have fewer developers/testers. While that could be an outcome of automation, I don't think it's a valuable argument.&lt;/p&gt;

&lt;p&gt;In all the scenarios above, having an extra human around wouldn't have necessarily helped. That's because human's have blind spots, and many of them are the same. Teams have collective blindspots and that's difficult to get around. We naturally tend to focus on what's in front of us, forgetting about realities outside our own influence.&lt;/p&gt;

&lt;p&gt;UI testing isn't about replacing humans, but rather augmenting their abilities. We use automation to shore up our limitations, allowing us to focus on our strengths.&lt;/p&gt;

&lt;p&gt;Developers waste their time testing on hundreds of different devices, when they could instead let a computer do that part of the work. Your QA team wastes its time running through the same test scenario week after week, when instead they could be thinking of new and undiscovered test cases.&lt;/p&gt;

&lt;p&gt;UI automation isn't about replacing humans with machines, but rather giving us more freedom to work better than machines.&lt;/p&gt;

&lt;p&gt;And let's not forget, UI testing requires a fair amount of work. It's not magic (although it's okay to convince management it is). This brings me to an important consideration...&lt;/p&gt;

&lt;h3&gt;
  
  
  There Are Always Drawbacks
&lt;/h3&gt;

&lt;p&gt;How long do you think it takes to get a set of automated tests up and running? A week... maybe two?&lt;/p&gt;

&lt;p&gt;Sure, if all you want to do is test that a page loads properly.&lt;/p&gt;

&lt;p&gt;But websites are incredibly complex — the number of features we jam on a page grows each day.&lt;/p&gt;

&lt;p&gt;Consider a "simple" homepage. Here are some things you'll want to test on it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do all the parts look right on a laptop and desktop computer?&lt;/li&gt;
&lt;li&gt;Do all the parts look right on a tablet?&lt;/li&gt;
&lt;li&gt;Do all the parts look right on a phone?&lt;/li&gt;
&lt;li&gt;Does the site navigation work?&lt;/li&gt;
&lt;li&gt;Does the "need help" chatbox pop up after five seconds?&lt;/li&gt;
&lt;li&gt;Does the autocomplete in the site searchbar work?&lt;/li&gt;
&lt;li&gt;Does the hidden menu show after you click the menu icon?&lt;/li&gt;
&lt;li&gt;Does the carousel on the homepage rotate correctly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, I'll stop there. Hopefully you get my point that there's a lot to test even on a single page. A basic script that loads a page doesn't provide much reassurance. &lt;/p&gt;

&lt;p&gt;So if you want to test all your functionality on all your pages, you're going to have to write a lot of code.&lt;/p&gt;

&lt;p&gt;Covering all of that ground takes time. Time that could be spent on other, possibly more important, tasks.&lt;/p&gt;

&lt;p&gt;And as you're writing test after test, the website your testing is going to keep changing. New features and fixes will be continuously introduced. The same feature will be tweaked again and again, causing your once-solid test suite to mysteriously start failing.&lt;/p&gt;

&lt;p&gt;When the glorious day comes and you're "done" writing tests, you still have to maintain them. Now, there are ways to write tests to make them more maintainable, and we'll cover that throughout the examples, but there's no such thing as a future-proof test. You're always going to need to update it.&lt;/p&gt;

&lt;p&gt;There's one more important point to consider.&lt;/p&gt;

&lt;p&gt;While you'll breeze through some parts of test writing, expect to sink 80% of your time figuring out how to test that special 20% of your site's functionality. There are many areas of writing tests that aren't trivial. It's not as simple as calling the command to fill out a textbox and click the submit button. &lt;/p&gt;

&lt;p&gt;You'll need to work with databases, integrate with third-party services and see if you can get commands to work in browsers with poor automation support. You're also going to run into instances where the way the website was coded just doesn't jibe with test automation. &lt;/p&gt;

&lt;p&gt;Animations are a good example of that. How do you test that an animation works? You can fairly easily check the properties before and after an animation, but what about everything in between those two states?&lt;/p&gt;

&lt;p&gt;Honestly, you'd need to do a screen recording of every frame of the animation, and compare that screen recording to a previous run to see if they match. I don't know about you, but that doesn't sound easy to me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simpler Sites for UI Testing
&lt;/h3&gt;

&lt;p&gt;If you find yourself facing a complex site that would require major work to test properly, there are other options to gain some value without too much effort.&lt;/p&gt;

&lt;p&gt;Instead of testing a fully working site, you may want to create a variation of your site that represents portions of the real thing. For example, pattern libraries are a popular option out there, especially for larger websites. &lt;/p&gt;

&lt;p&gt;In case you're not familiar with them, pattern libraries are essentially living demos of the components that make up a website's interface. Mailchimp has a public pattern library if you'd like to see one in action (&lt;a href="https://ux.mailchimp.com/patterns"&gt;https://ux.mailchimp.com/patterns&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For instance, a pattern library may contain standalone versions of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Site layout components like the main navigation and site footer&lt;/li&gt;
&lt;li&gt;Components used across multiple pages, like buttons, form inputs, and tabs&lt;/li&gt;
&lt;li&gt;Style guidelines for simple page elements like links, headings, and lists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pattern libraries are very helpful for teams, to document how the website should look and act. If you're tasked with adding a sortable table to your companies site, having a pattern library with a living example of one makes the job simple.&lt;/p&gt;

&lt;p&gt;They're also useful for testers, as it gives us testable examples of individual components isolated from the complexity of the full website. &lt;/p&gt;

&lt;h3&gt;
  
  
  Skipping Automation is Sometimes the Best Option
&lt;/h3&gt;

&lt;p&gt;Hopefully I haven't scared you away from UI test automation entirely. I only wanted to get you thinking about the whole picture.&lt;/p&gt;

&lt;p&gt;And that picture should include saying, "Maybe we shouldn't write test automation for that... at least not yet."&lt;/p&gt;

&lt;p&gt;Let's consider a few things...&lt;/p&gt;

&lt;h4&gt;
  
  
  New Features Aren't User Tested
&lt;/h4&gt;

&lt;p&gt;Business is booming and your team is tasked with a brand-new feature idea that management thinks the customer will love.  While it's tempting to say, "Yes, and let's write tests to go side-by-side with this new feature," it might not be the right time.&lt;/p&gt;

&lt;p&gt;This brand-new feature has never seen the light of day, and the second a customer sees it there's going to be something they don't like about it. If a decision is made to rework the concept based on customer feedback, all those tests you've written become useless. &lt;/p&gt;

&lt;p&gt;There's no point in writing a test if you haven't user-tested your site. So before you spend time writing assertions, ensure the assumptions about the user interactions are initially put to the test.&lt;/p&gt;

&lt;h4&gt;
  
  
  Time Writing Tests Takes Away from Writing Features
&lt;/h4&gt;

&lt;p&gt;You're not paid to write tests; tests only serve the application they're testing. If an app is useless, tests won't help.&lt;/p&gt;

&lt;p&gt;If you're working on a side project for a tool that no one uses, spending time writing tests takes away from time spent on more important tasks, like getting people to use your work.&lt;/p&gt;

&lt;p&gt;Users don't care whether you have good unit tests. There's no difference between an unused tool and an unused unit tested tool.&lt;/p&gt;

&lt;p&gt;Let yourself have untested code. Worry about that problem when it actually becomes one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tests Are Only Valuable When You Use Them
&lt;/h4&gt;

&lt;p&gt;Don't write more tests when you're not using the ones you already have.&lt;/p&gt;

&lt;p&gt;If you have 500 UI tests, but never put in the time to integrate them in your build and deployment process, you have 500 useless tests. Writing 500 more won't help.&lt;/p&gt;

&lt;p&gt;Your tests should run on every code push. They should run before every deploy. Every developer on the team should see that the tests passed or failed.&lt;/p&gt;

&lt;p&gt;If that's not true, you shouldn't be writing more tests, you should be taking advantage of the tests you already have. &lt;/p&gt;

&lt;h4&gt;
  
  
  Parts of the Site Might be Better Tested by People
&lt;/h4&gt;

&lt;p&gt;Remember when I said tests shouldn't replace people, but rather augment their abilities. Well, in the scenario of testing an animation, we were stuck with a really complex solution. What if we just went with manual visual validation of the effect? &lt;/p&gt;

&lt;p&gt;It's okay to have some parts of your site that are too complex for automation. Grab that low-hanging fruit and leave the stuff higher in the tree for a later time when you have a ladder. &lt;/p&gt;

&lt;h3&gt;
  
  
  Are Tests Worth It Then?
&lt;/h3&gt;

&lt;p&gt;I've outlined the benefits and drawbacks of test automation, including reasons to entirely skip some of it.&lt;/p&gt;

&lt;p&gt;So how do you ensure you're getting more benefits than drawbacks? Focus on these two goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure you're gaining value out of every test you write&lt;/li&gt;
&lt;li&gt;Ensure you're selling that value to those in charge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's really easy to get caught up in automation, trying to cover every nook and cranny of the site. But if a feature of your site doesn't provide much value, how much less value would a test for that feature be? &lt;/p&gt;

&lt;p&gt;The site login component breaking... that's bad. The site's About page having a typo... not such a big deal. Sure, we'd want to fix it, but it (hopefully) won't cost the company a lot of money.&lt;/p&gt;

&lt;p&gt;By focusing on gaining and selling that value, you can keep yourself honest in your test writing, and focus on what's important: having a site that's running smoothly and providing value to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn a Better Way To Test
&lt;/h2&gt;

&lt;p&gt;There's a lot more to UI Test Automation than I've briefly covered here, including code! &lt;/p&gt;

&lt;p&gt;In fact, this was just a short excerpt from &lt;a href="https://leanpub.com/webapp-testing-guidebook"&gt;The Web App Testing Guidebook&lt;/a&gt;. In the book, I cover what WebdriverIO can do and how you'll be using it day-to-day. I've built the examples around real-world scenarios that demonstrate how you would actually set things up. It's not just "what", but also "how to get there" with reasoning around every decision. &lt;a href="https://leanpub.com/webapp-testing-guidebook"&gt;Grab a copy today at LeanPub!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Header Photo by &lt;a href="https://unsplash.com/@rocknrollmonkey"&gt;Rock'n Roll Monkey on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Piano Robot Photo by &lt;a href="https://unsplash.com/photos/U3sOwViXhkY"&gt;Franck V. on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>5 Hacks to Speed Up Your TypeScript Development | Satire</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Tue, 21 Jan 2020 16:44:16 +0000</pubDate>
      <link>https://forem.com/klamping/5-hacks-to-speed-up-your-typescript-development-satire-2l46</link>
      <guid>https://forem.com/klamping/5-hacks-to-speed-up-your-typescript-development-satire-2l46</guid>
      <description>&lt;p&gt;Are you an experienced dev, but new to TypeScript? Or maybe interested in the technology, but worried it'll slow you down with unnecessary cruft?&lt;/p&gt;

&lt;p&gt;No worries! I've got year of experience with TypeScript and have learned some handy tricks to help keep me coding. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;code&gt;// @ts-ignore&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Some pesky line of code causing your compilation problems? No worries, just throw &lt;code&gt;// @ts-ignore&lt;/code&gt; on the line before and now your issues are all solved. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tVR07RX_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r45cydssqrmuz7depozf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tVR07RX_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r45cydssqrmuz7depozf.png" alt="TypeScript errors yelling at a cat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're feeling frisky, hack an entire file by adding &lt;code&gt;/* tslint:disable */&lt;/code&gt; to the top of it and now you don't need to worry about any TypeScript issues holding you back for that entire chunk of code. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. the 'any' type
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://knowyourmeme.com/memes/i-dont-like-sand"&gt;I don't like types&lt;/a&gt;. They're strict and restrictive and irritating and they get everywhere. So how do you eat your types and keep them too? Use the &lt;code&gt;any&lt;/code&gt; type!&lt;/p&gt;

&lt;p&gt;Say you want to create a new variable that'll probably be a &lt;code&gt;string&lt;/code&gt;. Instead of typing it as such and restricting yourself from future changes, just type it as &lt;code&gt;any&lt;/code&gt; and now you have free range to change things as necessary!&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myString&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;down with sand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Want to change that to an integer lately? If you had strictly typed it, you'd have to update the code in two places. Using &lt;code&gt;any&lt;/code&gt;, you don't have to worry about that! Genius!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Don't type variables
&lt;/h2&gt;

&lt;p&gt;I know I just talked about using &lt;code&gt;any&lt;/code&gt; to avoid strict typing, but I'm going to give you a pro tip: you don't have to define any typing at all!&lt;/p&gt;

&lt;p&gt;That's right, even in TypeScript, you don't actually have to type any of your scripts! I'm a huge proponent of reducing code, and this goes right along with that best practice. Compare these two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myString&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;down with sand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;down with sand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can clearly see how the second line involves less complicated code than the first. Only a Java developer would prefer the former. &lt;/p&gt;

&lt;p&gt;So next time your tempted to bloat your codebase with types, just don't. This one simple trick will save your bytes and bytes of code!&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Don't define a function return type
&lt;/h2&gt;

&lt;p&gt;If we don't have to type our variables, then why do we have to type our function returns? Answer: we do not! HAHA&lt;/p&gt;

&lt;p&gt;It's a code smell to restrict your function to a single return type. Why? Because it's extra code!&lt;/p&gt;

&lt;p&gt;Compare these two functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What's the difference between the two? An expert will happily tell you that the latter won't bind you into some pre-optimized state that can never be changed without breaking all your dependent programs. We don't want that now do we. Do we!?&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Ensure 'strict' is always set to false in your tsconfig
&lt;/h2&gt;

&lt;p&gt;There's one caveat to all of the above. You can't improve your code with these hot hacks if you've got 'strict' set to &lt;code&gt;true&lt;/code&gt; in your &lt;code&gt;tsconfig&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;That's why you should never, under any circumstances, ever, not even once, set &lt;code&gt;strict&lt;/code&gt; to any value other than &lt;code&gt;false&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Really, ask yourself, do you want to be &lt;code&gt;strict&lt;/code&gt;? That's not fun, you Debbie Downer. Let people be free and let your code have the flexibility to live in a world not held down by arbitrary restrictions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope these elite tricks help you in your job. TypeScript is here to stay for sure. But you don't have to let it control who you are or change your style. Follow these 5 simple hacks and you're set for instant success!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>satire</category>
    </item>
    <item>
      <title>25 Projects That Changed the JavaScript Landscape over the 2010s (25-21)</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Thu, 16 Jan 2020 15:11:18 +0000</pubDate>
      <link>https://forem.com/klamping/25-projects-that-changed-the-javascript-landscape-over-the-2010s-25-21-11ii</link>
      <guid>https://forem.com/klamping/25-projects-that-changed-the-javascript-landscape-over-the-2010s-25-21-11ii</guid>
      <description>&lt;p&gt;I'm tired of "Tools &lt;em&gt;Every&lt;/em&gt; Developer in 2020 Must Know" articles. &lt;/p&gt;

&lt;p&gt;They're mostly re-used content from the previous year and usually only serve as clickbait to get viewers to sites with questionable motivations. They're boring, unhelpful and undistinguishable from all the others out there.&lt;/p&gt;

&lt;p&gt;Yes, we all know React is an important tool to know about. Give it a rest!  Try instead to formulate a unique thought that might make others rethink the popular opinion they've heard time and time again.&lt;/p&gt;

&lt;p&gt;So, how about an article not about "tools developers must know", but rather, "tools that changed what developers knew"?&lt;/p&gt;

&lt;p&gt;In this list, I'm highlighting 25 JavaScript tools that I believe changed the industry over the past decade. All are/were popular, but it isn't ordered by popularity. Instead, we're looking at how revolutionary the ideas were, and how much they impact the JavaScript landscape.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caveat: Knowing the "first publish date" of a tool is difficult, so I'm focused more on when the tool was popularized than when it was first published.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  25. Istanbul
&lt;/h2&gt;

&lt;p&gt;Honestly, it's harder to pick out #25 than it is #1.  But I say &lt;a href="https://istanbul.js.org/" rel="noopener noreferrer"&gt;Istanbul&lt;/a&gt; deserves to make the list over others for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It introduced code coverage to JavaScript, which started the decade with few automated testing tools out there. Istanbul promoted the testing discipline by making the lack of it much more visible. &lt;/li&gt;
&lt;li&gt;It's maintained that status as the "go-to code coverage" tool for the entire decade. Throughout the years, it's continued to be well-maintained and updated, which is a huge feat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ct0hdnf65va7ntawewu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ct0hdnf65va7ntawewu.png" alt="Example terminal output of Instanbul"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite my opinion that code coverage is over-emphasized in importance, it's a tough argument that Istanbul hasn't benefitted the industry through better test practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  24. Prettier
&lt;/h2&gt;

&lt;p&gt;I've used &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; and I didn't like it. Kind of.&lt;/p&gt;

&lt;p&gt;Okay, Prettier is extremely opinionated, and if that opinion is different from yours, you kind of just have to deal with it. &lt;/p&gt;

&lt;p&gt;And I think that's the beauty of the tool. Bikeshedding is a real problem in dev teams, and tabs-vs-spaces arguments can quickly turn from fun to frustration when it's your daily life. &lt;/p&gt;

&lt;p&gt;Prettier says "Stop!" to all of that. You install the tool, go with what it says, and it takes care of the rest. No options, but no frustrating "Code Style Review" meetings. &lt;/p&gt;

&lt;h2&gt;
  
  
  23. CypressIO
&lt;/h2&gt;

&lt;p&gt;Developed in 2014, &lt;a href="https://www.cypress.io/" rel="noopener noreferrer"&gt;CypressIO&lt;/a&gt; has grown to become one of the most popular automated testing tools out there. That's not so revolutionary, until you realize they did it without supporting one of the most requested features out there (cross-browser testing).&lt;/p&gt;

&lt;p&gt;The CypressIO team had a hunch that easy-to-write (and run) test automation was by far more important than any other feature. So that's what they focused on, to which they've had much success.&lt;/p&gt;

&lt;p&gt;CypressIO is a reminder that many "needs" of customers are really just what they think they should want. You can be revolutionary by not doing something, allowing you to do a more important thing 10x better than before.&lt;/p&gt;

&lt;h2&gt;
  
  
  22. YUI3
&lt;/h2&gt;

&lt;p&gt;You may not know &lt;a href="https://yuilibrary.com/" rel="noopener noreferrer"&gt;YUI3&lt;/a&gt;. The library hasn't had a code commit since 2014. &lt;a href="https://www.youtube.com/watch?v=MH7KYmGnj40" rel="noopener noreferrer"&gt;It's dead, Jim&lt;/a&gt;. Aside from that, its main competitor was jQuery, which held market-domination for its entire life.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcwq0rjtdo4lt7vetn8ph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcwq0rjtdo4lt7vetn8ph.png" alt="YUI Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the folks at YUI3 were one of the first ambitious groups to create an entire library aimed at solving all of the pressing problems for front-end engineers. &lt;/p&gt;

&lt;p&gt;They created a module loading system before module loading systems were cool. &lt;/p&gt;

&lt;p&gt;They created a unit test framework before unit test frameworks were cool. &lt;/p&gt;

&lt;p&gt;They created... well, the idea was that they tried to create everything. They took a look at the entire ecosystem of the front-end and said, "here's a solution."&lt;/p&gt;

&lt;p&gt;All this while at a company (Yahoo!) which struggled year-over-year to get past the giant of Google. &lt;/p&gt;

&lt;p&gt;YUI3 may not be remembered by most, but many developers learned many new ideas from it, myself included.&lt;/p&gt;

&lt;h2&gt;
  
  
  21. Ionic
&lt;/h2&gt;

&lt;p&gt;Attempts to build "web-based mobile apps" existed before &lt;a href="https://ionicframework.com" rel="noopener noreferrer"&gt;Ionic&lt;/a&gt;, but none seemed to capture the scope that Ionic has sought and achieved. Riding the furvor around Angular, Ionic offered devs like me a streamlined approach to developing mobile apps using the Angular ecosystem.&lt;/p&gt;

&lt;p&gt;I'd say they've succeeded at their mission, as I was able to use Ionic to publish multiple tools to the Google Play and iOS App Store using their functionality. This may not seem like much, but it was important to me. &lt;/p&gt;

&lt;p&gt;Ionic changed the landscape for front-end devs by giving us the functionality we needed to make it through the endless approval process involved in publishing a mobile app. And we were able to do it all using HTML, CSS and JS.&lt;/p&gt;

&lt;p&gt;They've made a wealth of changes since I last used them a few years back, and the future for the tool looks brighter than ever. If you haven't checked out Ionic yet, take a look and see what you can do with a spare evening or two. It's really fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's coming up!
&lt;/h2&gt;

&lt;p&gt;As much as I'd love to finish covering the other 20 tools right now, I know it's best to split this into a multi-part series. Up next are tools 20-16, all of which focused on tooling/ecosystem improvements. Can you guess what they might be?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I Hate Remote Working (But Still Prefer it to an Open Office Environment)</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Wed, 23 Oct 2019 16:22:58 +0000</pubDate>
      <link>https://forem.com/klamping/why-i-hate-remote-working-but-still-prefer-it-to-an-open-office-environment-1d6h</link>
      <guid>https://forem.com/klamping/why-i-hate-remote-working-but-still-prefer-it-to-an-open-office-environment-1d6h</guid>
      <description>&lt;p&gt;Remote working is considered the next revolution in the workplace, but I kind of hate it. What would cause me, who wrote an article titled "&lt;a href="https://dev.to/klamping/why-i-love-remote-working-1j60"&gt;Why I Love Remote Working&lt;/a&gt;", to say that? Honesty.&lt;/p&gt;

&lt;p&gt;There are many reasons to hate remote working, and I find it important to recognize those drawbacks. By being open about the issues remote working introduces, we can better equip ourselves to grow the practice.&lt;/p&gt;

&lt;p&gt;Many companies are taking a "&lt;a href="https://www.remoteonly.org/" rel="noopener noreferrer"&gt;remote-only&lt;/a&gt;" approach. Because of this growing trend, I've been able to work remotely for over 4 years. In that time, I've faced many challenges that hopefully I can provide insight on. &lt;/p&gt;

&lt;h2&gt;
  
  
  Remote work is lonely business
&lt;/h2&gt;

&lt;p&gt;The number one drawback of remote working is it's isolation. There are no random interactions during coffee breaks, no running to grab lunch with co-worker, and no friday afternoon nerf battles (unless you have kids at home). &lt;/p&gt;

&lt;p&gt;While an introvert like myself finds solace in not being surrounded by people all day, it's unhealthy to be isolated from people for extended periods of time. &lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;I believe that companies who support remote work should absolutely pay for a coffeeshop card and/or co-working space. This can easily be justified by comparing it to the cost of having to have office space. It's a small gesture that can have a big impact on someone's mental health. Companies should have an intrinsic motivation to take care of their employees, and this is a good step towards that.&lt;/p&gt;

&lt;p&gt;Also, as a remote employee, make extra effort to be part of local tech groups. Also, join non-tech, hobby-related groups in town. Make up for that missing face-to-face time to help stay connected with humanity.&lt;/p&gt;

&lt;h2&gt;
  
  
  It can lead to a less active day
&lt;/h2&gt;

&lt;p&gt;The joke about remote working is that your commute is the 10 steps from the kitchen to your desk. That's great, except when those are the only steps you're getting in all day. &lt;/p&gt;

&lt;p&gt;In an office setting, you're walking to/from the parking lot, to/from the bathroom and jumping from meeting to meeting. While you can certainly still have a low-level of movement overall in the day, at least you're forced to walk some sort of extended distance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Commit yourself to at least one physical activity in the middle of the workday. Don't feel guilty for spending time being active. It's your health!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fs6fr5dq5kcpyr3oseycw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fs6fr5dq5kcpyr3oseycw.jpg" alt="Three people lifting weights"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many companies offer gym memberships, so take advantage of that. Also, if your company has an on-site gym (several larger companies do), ask you manager for a similar benefit. Again, you're saving the company money in not having to provide office space for you, so they should be able to find it in the budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  It can hurt your career (slower promotions, more difficult to break into management)
&lt;/h2&gt;

&lt;p&gt;In some companies, there's definitely a glass ceiling for remote workers. While the company may be okay with Individual Contributors working remote, they want their management level employees to all be co-located. This means, as a remote worker, your promotions will always be limited at that company. It's frustrating, but it is also reality in many situations. &lt;/p&gt;

&lt;p&gt;Another unfortunate truth is that if you're one of the only remote workers on your team, your work won't be as visible as those in the office. This means when it comes time for promotions, managers will be thinking about those they've seen in the office producing, not those out-of-sight doing quiet work in the background. Yes, this is a management problem (as they should be promoting/rewarding their most productive employees), but it's also your responsibility to work through.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Make sure you know where you want to be five years down the road. Don't rely on a big management mindset shift happening in regards to management being able to work remote. It may happen, but it's a big shift for many companies who are often afraid of that level of change.&lt;/p&gt;

&lt;p&gt;Openly advocate for yourself to grow your career. Good advice in general, but absoutely necessary in this instance. I won't go into detail on what that means, because there are many great articles already written on it here and elsewhere on the internet.&lt;/p&gt;

&lt;p&gt;Also, "brag" about your work. In chat rooms, post updates about things your working on and things that are causing trouble. Be visible there because you're not visible in the office.&lt;/p&gt;

&lt;h2&gt;
  
  
  More competition, less pay
&lt;/h2&gt;

&lt;p&gt;Remote work is amazing because it gives you the freedom to work anywhere in the world. But this also means that anyone in the world can apply for the same job you want. Since cost-of-living differs dramatically across the globe, this means you may be competing with someone who can work for significantly less income than you. As a business, they're motivated to keep expenses low, and if someone can do just as effective job as you for half the rate, they're going to take that deal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Don't be afraid to ask for the rate you need in order to live, but also consider using your freedom to move to a lower cost-of-living (COL) location. Give yourself a competitive advantage in this regard. There are some very beautiful, smaller cities across the globe. I recently moved from a large city to one a tenth of its size and I love it. The COL is about the same (it was a lower COL large city compared to NYC, etc), but the city feel so much more accessible. I'm able to bike almost anywhere around town and I never run into big-city traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F97zb5ufgkmjw90uel0j0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F97zb5ufgkmjw90uel0j0.jpg" alt="View of small town downtown district"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, in interviews, really push your soft-skills experience. This can be a major difference between you and other applicants, and many companies will happily pay extra on the bet that they're getting a more mature employee.&lt;/p&gt;

&lt;p&gt;Finally, many companies in high COL areas are looking outside their city for employees who won't break the bank in salary. Watch out for those jobs, as they'll happily pay the same or higher than local companies, since it's still cheaper than hiring in their city. &lt;/p&gt;

&lt;h2&gt;
  
  
  Harder to get started in the morning and end in the evening
&lt;/h2&gt;

&lt;p&gt;Without a commute and walk into an official office, it can be a little difficult to make that transition from waking up to being productive. And then when the end of the day comes, it can be tempting to just fix that one last bug. You don't see everyone else in the office leaving, so you forget that you should probably head out as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Find a morning routine that works. Pomodoro is a great option to get started. I do 10 minutes focused work with an optional 2 minute break. Many times I skip the break when I'm in a flow. But knowing that I'm only committing to 10 minutes, instead of that full 8-hour work day, makes all the difference in my getting started.&lt;/p&gt;

&lt;p&gt;And at the end of the workday, remember that often, stepping away from the problem for the day can be the perfect solution. Just this morning I fixed a bug in five minutes that I was struggling with all yesterday afternoon. It was only by taking a break from the issue that I was able to break out of the unproductive debugging I was doing and see the code in a new light.&lt;/p&gt;

&lt;h2&gt;
  
  
  You're constantly reminded of all the work that needs to be done around the house
&lt;/h2&gt;

&lt;p&gt;No one keeps their dirty laundry at the office (well, some co-workers do, but let's not talk about them). But at home, anytime you take a break, you're surrounded by all the house chores you need to get done. "Let me grab a quick snack oh yeah the sink is full of dirty dishes". "I'm going to take a quick break oh no the cat knocked over the magazine stack I might as well pick it up oh and who put that there, let me put that away really quick and I should really organize this drawer so it's easier to find things..."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx6nrsnrqh2l4ycneofte.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx6nrsnrqh2l4ycneofte.jpg" alt="Cat with blue eyes looking shy like it did something wrong and knows it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You get the idea. Those are thoughts we have in an office (most of the time), since we're not surrounded by our never-ending chore list. Aside from watering a desk plant every now and then, most of the office maintenance is handed by a dedicated crew. That's not the truth at home and it can constantly take over what are supposed to your breaks.&lt;/p&gt;

&lt;p&gt;And honestly, when facing a particularly tough situation at work, you might actually be motivated to do the dishes instead. Not that this isn't an effective "step back" strategy in some situations, you just shouldn't use it as a reason to avoid the job your paid to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Make room for an office space. Have dedicated snacks/water in your office. Have a good break area that isn't a constant reminder of all you need to get done around the house.&lt;/p&gt;

&lt;p&gt;If you don't have that as an option, get out of your house to a nearby coffeeshop, hotel lobby, car dealership (pretend your car is being worked on while you pig out on their free coffee and donunts). Stop mixing your personal workspace with your professional workspace. It'll only cause you to stress out and raise your anxiety to unproductive levels. &lt;/p&gt;

&lt;h2&gt;
  
  
  I really do love remote working
&lt;/h2&gt;

&lt;p&gt;Even with all of these reasons to hate it, remote working is definitely for me. There are always going to be drawbacks of certain working situations, and it's useless to deny them. If you work remotely, take a look at things that bother you and address them. Don't pretend they don't exist, like you're living in some make-believe world.&lt;/p&gt;

&lt;p&gt;Remote workers, what things do you hate about the life? What solutions have you found to address them?&lt;/p&gt;

&lt;p&gt;Also, &lt;a href="https://theoatmeal.com/comics/working_home" rel="noopener noreferrer"&gt;this Oatmeal comic on the love/hate relationship with remote working&lt;/a&gt; is fantastic!&lt;/p&gt;

&lt;p&gt;Photo credits (via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;):&lt;br&gt;
&lt;a href="https://unsplash.com/@maundytime" rel="noopener noreferrer"&gt;Fork Photo by Catt Liu&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unsplash.com/photos/Lx_GDv7VA9M" rel="noopener noreferrer"&gt;Workout Photo by Sven Mieke&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unsplash.com/photos/QrgRXH81DXk" rel="noopener noreferrer"&gt;City Photo by Monica Bourgeau&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unsplash.com/photos/OzAeZPNsLXk" rel="noopener noreferrer"&gt;Cat Photo by Max Baskakov&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>remote</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Does blogging really help your career?</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Wed, 28 Aug 2019 01:57:42 +0000</pubDate>
      <link>https://forem.com/klamping/does-blogging-really-help-your-career-3cg</link>
      <guid>https://forem.com/klamping/does-blogging-really-help-your-career-3cg</guid>
      <description>&lt;p&gt;I love the community here and the fact that we can openly share ideas between one another.&lt;/p&gt;

&lt;p&gt;But I keep hearing/reading from various sources (not specifically here) that one of the great benefits of writing tutorials/blogging is how much it helps your career through connections and such.&lt;/p&gt;

&lt;p&gt;I feel like this is akin to people saying how free work is all about "exposure" or that "it's great for your portfolio!"&lt;/p&gt;

&lt;p&gt;Aside from maybe helping me get my first job out of college, I can't recall a single interview I've had where they cared about what I've written. &lt;/p&gt;

&lt;p&gt;They may care a little about side projects, in that it checks the box that you're willing to work outside of work, but the difference between having written a single article and having written 500 articles seems to be nil.&lt;/p&gt;

&lt;p&gt;I'm not trying to be selfish and stating that there's no point in doing this if it doesn't advance my career. There are many, many reasons to write that I find very valuable (and I'm sure many of you would agree with).&lt;/p&gt;

&lt;p&gt;I guess I just wish people wouldn't give that specific advice without evidence to back it up. Blogging won't land you a job, at least not in the near-term. It takes months (even years) of effort for it to start to have any professional effect.&lt;/p&gt;

&lt;p&gt;What are your experiences? Has writing here (or elsewhere) helped you land that killer job? Am I completely wrong in my objection?&lt;/p&gt;

&lt;p&gt;Edit: These are awesome responses everyone! It's helping remind me that while we may never hear "You wrote this blog post therefore you're hired", it helps us learn the soft skills needed in interviews and communication in general.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>writing</category>
      <category>career</category>
    </item>
    <item>
      <title>Here, There be Documentation</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Wed, 07 Aug 2019 16:11:09 +0000</pubDate>
      <link>https://forem.com/klamping/here-there-be-documentation-2ij6</link>
      <guid>https://forem.com/klamping/here-there-be-documentation-2ij6</guid>
      <description>&lt;p&gt;"Honestly, does the client even care if the code is formatted or not?"&lt;/p&gt;

&lt;p&gt;Have you ever had someone tell you this? Or maybe you're guilty of repeating that line. I know I am.&lt;/p&gt;

&lt;p&gt;"Sure, I know standards are important, but we really don't have time to worry about that right now. The client just wants this feature shipped."&lt;/p&gt;

&lt;p&gt;That's hard to argue against. The end result is what matters, especially when working for someone else. One the other hand, the idea of standards is to allow the team to ship faster (even if it takes an up-front investment). The client definitely cares about that.&lt;/p&gt;

&lt;p&gt;So why are we unable to connect the dots between standards and the client's satisfaction? I have a theory.&lt;/p&gt;

&lt;p&gt;Teams know standards are important, but they don't know how to make them happen. Typically, best practices becoming someone's "thing". Unit Testing is Allison's "thing". Code semantics is Bobby's "thing". Accessibility is Rachel's "thing".&lt;/p&gt;

&lt;p&gt;But those "things" never become part of the collective mindset. There's no team ownership, no binding vision; just a bunch of things people are individually interested in. Managers encourage individual ownership, but withhold authority to implement the needed team-wide change.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Adventure Starts
&lt;/h2&gt;

&lt;p&gt;Let's think about what happens when individual "coding standard champions" are declared. Even when the team likes the idea, only the Champion makes the long-term changes needed to implement the solution.&lt;/p&gt;

&lt;p&gt;Rather than addressing the lack of real buy-in from the group and the need for standards enforcement across the team, the Champion is encouraged to take individual accountability by management. This would look good on their mid-year review after all.&lt;/p&gt;

&lt;p&gt;So the Champion goes off, fighting a huge battle to convert the codebase from the wicked ways of the past. They defeat the evil Tab dragon and travel back home with their Spaces safely in hand. It takes longer than expected, but feels good to have completed the work.&lt;/p&gt;

&lt;p&gt;But what do they see when they arrive back home, weary from their travels?&lt;/p&gt;

&lt;p&gt;Hundreds of new dragons hatching in the forms of poorly documented code and untested features. Why is no one dealing with these dragons before they become too big?! Oh, because it was the Champions thing. They're in charge of that.&lt;/p&gt;

&lt;p&gt;So the Champion, still afraid to ask for real help, starts slaying these new dragons left and right. But then someone needs an outside resource and leaves the town gate open. New dragons come flooding in. Soon the Champion is overwhelmed with work, and fears another gate will be let open at any point in time, continuing the downward spiral.&lt;/p&gt;

&lt;p&gt;So they put down their sword and the dragons take over. Someone asks months later, "Oh hey, weren't you fighting these things?" to which the Champion responds, "Yeah, but the client doesn't really care about dragons in our village, right? They just want to know the festival is going to happen and it's already a tight enough deadline."&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Runs Out
&lt;/h2&gt;

&lt;p&gt;Work continues and the festival time is near. There are dragons everywhere. They're eating the food. They're burning down the tents. Everyone is frantically running around trying to repair the chaos, but no one can get a handle on it.&lt;/p&gt;

&lt;p&gt;The client is understandably upset. They hear talk of dragons ruining their festival and want to know why. To calm the client, promises are made to eradicate the dragons causing this chaos. But the festival must be moved back a couple weeks. The client, afraid to lose their investment, accepts the proposal.&lt;/p&gt;

&lt;p&gt;Meetings are set up defining how best to slay these creatures. Champions are declared to deal with specific colors of dragons. Joe will take the green ones. Marcy will take the red. We'll meet in two weeks to see how things are going.&lt;/p&gt;

&lt;p&gt;So Joe and Marcy start slaying dragons left and right. They're starting to get a handle on it; even teaming up in parts of town where there are a lot of both kind. They feel refreshed to have an ally in this fight and feel like they're making real progress.&lt;/p&gt;

&lt;p&gt;Unknown to them though, the client is upset about the delay and wants a special tent installed as repayment. But Marcy is the only one who knows how to install that type of tent and she's already busy with very important work.&lt;/p&gt;

&lt;p&gt;Without another rational choice, management decides to bring an outside worker in who specializes in all sorts of tents. They've promised to get this one installed in under two days. And they do. A couple days later the tent is up and Marcy and Joe have finished their work. All seems well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden In Plain Sight
&lt;/h2&gt;

&lt;p&gt;The night before the big celebration, Marcy is walking around the various tents double checking tie downs and ensuring no dragons are lurking in dark corners. She comes to the special tent and notices something interesting about it. The beams holding the structure up are a different type of wood.&lt;/p&gt;

&lt;p&gt;That's strange. Normally these poles come from a specific lumber mill, known for its quality. These must be different.&lt;/p&gt;

&lt;p&gt;As she inspects closer, she notices strange holes in the wood. Then she notices it. The entire structure is swaying uneasily in the gentle breeze.&lt;/p&gt;

&lt;p&gt;She immediately understands what's happening. The builder used cheap, rotted lumber — Lumber that's filled with wood-boring insects. These bugs are gnawing at the material, tearing it to shreds. She runs for helps as several adult beetles fly by her ear towards a neighboring tent.&lt;/p&gt;

&lt;p&gt;She gathers the team in an emergency meeting. They decide they must hide the issue from the client. It's too late now to rebuild the structure; they can only hope it will survive the next few days of partying. They'll pull an all-nighter working to treat the bug infestation while the client sleeps.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Terrible Success
&lt;/h2&gt;

&lt;p&gt;It works. It works so well the client wants another party. In fact, the client wants parties like this every month. What a success for the team, right?&lt;/p&gt;

&lt;p&gt;But they know the real truth. Their fixes worked, but they were unable to stop the bugs from spreading. The adult beetles surely laid eggs in every piece of wood throughout the fairgrounds. If they don't spend every day working to treat new infestations, the bugs will once again take over.&lt;/p&gt;

&lt;p&gt;The damage done has required special scaffolding be put in to keep the tents sturdy. It's functional, but is delicate and difficult to adjust as the client's needs shift. They've already had to tell them that the jousting arena can't be upgraded because of "structural dependencies".&lt;/p&gt;

&lt;p&gt;Joe, Marcy, and the rest of the team, once brave adventurers setting out to explore the landscape, are now confined to the city walls in a never-ending battle with the insects. Insects they had worked so hard at the start to keep out. They used the right materials sourced from the right people made in the right way.&lt;/p&gt;

&lt;p&gt;But the client didn't care about that. The client just wanted a tent. And now Marcy has stopped caring as well. Why worry about using quality wood when it will just end up rotted anyway? This endless bug-squashing has worn her down. She's no longer motivated to start her day. Why should she? It's nothing new... just playing wack-a-mole against the insects.&lt;/p&gt;

&lt;p&gt;New workers are brought in as she struggles to keep up. They also don't care about quality. They just need the steady income. They're satisfied squashing bugs. Every new tent for them means more job security. So they put up as many tents as they can, using whatever materials they find lying around.&lt;/p&gt;

&lt;p&gt;Soon, the town becomes so filled with rotted wood that it becomes impossible to keep up the fight against the insects. Word is that the client doesn't like all the beetles buzzing around from square to square. A rumor has spread that the client is looking to move to a different town and a different company. A company that promises standards and quality craftsmanship; A company like this used one to be.&lt;/p&gt;

&lt;h1&gt;
  
  
  A New Start
&lt;/h1&gt;

&lt;p&gt;In one last valiant effort, the team convinces the client to tear everything down and rebuild the city. They'll use the right materials this time. In fact, they'll invest in using the latest technology. Technology that comes with built-in pesticide. The beams are built to prevent insects from nesting, so it shouldn't be an issue.&lt;/p&gt;

&lt;p&gt;The client is convinced and work begins.&lt;/p&gt;

&lt;p&gt;Marcy, finding fresh motivation that she hasn't felt in years, sets up several meetings to help ensure standards are in place to keep this from ever happening again. She's excited to apply what she has learned to this new project. So many new ideas to try.&lt;/p&gt;

&lt;p&gt;Her first: we must have quality control and follow strict guidelines in how work is done. People are excited, but a little skeptical. Won't that take extra time? Isn't this project big enough?&lt;/p&gt;

&lt;p&gt;And honestly, does the client even care if the code is formatted or not?&lt;/p&gt;




&lt;p&gt;Originally posted on &lt;a href="https://blog.kevinlamping.com/here-there-be-documentation/"&gt;https://blog.kevinlamping.com/here-there-be-documentation/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Header photo credit: &lt;a href="https://unsplash.com/photos/vVKbHNhu2ZU"&gt;https://unsplash.com/photos/vVKbHNhu2ZU&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>agile</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Visual Regression Testing is Stupid (but we can fix it)</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Thu, 13 Dec 2018 16:40:55 +0000</pubDate>
      <link>https://forem.com/klamping/visual-regression-testing-is-stupid-3cfn</link>
      <guid>https://forem.com/klamping/visual-regression-testing-is-stupid-3cfn</guid>
      <description>&lt;p&gt;The title of this post might seem odd coming from a guy who helps run &lt;a href=""&gt;a site on Visual Regression Testing&lt;/a&gt; (and has given many talks on the subject).&lt;/p&gt;

&lt;p&gt;But I really do believe it.&lt;/p&gt;

&lt;p&gt;I'll explain why in just a moment, but first, a primer if you're not familiar with the term.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is 'Visual Regression Testing'?
&lt;/h2&gt;

&lt;p&gt;You know those "spot the difference" puzzles? The ones where you need to find five changes between two very identical looking pictures?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq46zjhkyx253yvgw1ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq46zjhkyx253yvgw1ec.png" alt="Spot the difference image, with one picture having the mouth of a spaceship a slightly different size" width="595" height="361"&gt;&lt;/a&gt;&lt;/p&gt;
Leave a comment if you can spot the single difference



&lt;p&gt;Testers do that sort of thing every day.&lt;/p&gt;

&lt;p&gt;Anytime the CSS or HTML changes, we're stuck playing "spot the difference".&lt;/p&gt;

&lt;p&gt;But &lt;a href=""&gt;we're really bad&lt;/a&gt; at it. Like, &lt;a href=""&gt;really bad&lt;/a&gt;. (It's how magicians make their magic work)&lt;/p&gt;

&lt;p&gt;Visual Regression Testing aims to help us here by having a computer detect the differences for us.&lt;/p&gt;

&lt;p&gt;You start by storing a screenshot of the page in a good state. Then, after an update, you take a fresh screenshot and have the computer compare the two.&lt;/p&gt;

&lt;p&gt;Any differences between these two images causes the test to fail. It's actually really good at this, in a really dumb way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's stupid
&lt;/h2&gt;

&lt;p&gt;Basic image comparison is dumb.&lt;/p&gt;

&lt;p&gt;It just can't understand the subtleties of design, and how that design can change without breaking. This leads to a ton of false positives.&lt;/p&gt;

&lt;p&gt;Because web pages change. &lt;strong&gt;A lot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The content is always being updated; New features are added, old features removed. The design is always being tweaked.&lt;/p&gt;

&lt;p&gt;And don't even get me started on all the ways marketing wants to tinker with the site.&lt;/p&gt;

&lt;p&gt;If you're running basic image comparison, your tests are going to fail. &lt;strong&gt;All. The. Time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Believe me, I've been there. It sucks.&lt;/p&gt;

&lt;p&gt;It's like trying to detect earthquakes with a seismometer... a seismometer that's in a car hurtling down a washed out dirt road.&lt;/p&gt;

&lt;p&gt;You're going to get &lt;strong&gt;a lot of useless noise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To get around this, some libraries offer the option of defining an allowed 'diff percentage'. It's a number comparing the total percentage of differences versus the size of the image itself.&lt;/p&gt;

&lt;p&gt;If it's below that number, it'll say, "Hey, that's okay, we'll just accept that change because surely it means nothing..."&lt;/p&gt;

&lt;p&gt;What type of madness is that?!&lt;/p&gt;

&lt;p&gt;We're just going to define an arbitrary and completely subjective number that has no basis in reality and go with it?!&lt;/p&gt;

&lt;p&gt;Even the seismologist in the car thinks that's idiotic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to learn it some good
&lt;/h2&gt;

&lt;p&gt;All this may seem pretty harsh, and you may be thinking that it's all a lost cause, but I have some decent news.&lt;/p&gt;

&lt;p&gt;Just as &lt;a href=""&gt;scientists are smart enough to cancel out the noise from their measuring devices&lt;/a&gt;, we can improve our signal to noise ratio with a few tricks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take smaller screenshots
&lt;/h3&gt;

&lt;p&gt;The first and simplest method I recommend is to take smaller screenshots. That is, only take screenshots of individual components, and never of the entire webpage.&lt;/p&gt;

&lt;p&gt;The tool you use needs to support snapping individual sections of the page (this is usually done by passing in a CSS selector for a specific element).&lt;/p&gt;

&lt;p&gt;By reducing the size of your images, you're able to quickly identify what failed ('oh, the screenshot of the submit button').&lt;/p&gt;

&lt;p&gt;You also get to block out sections of the website constantly in motion (for instance, that third-party 'recommended items' widget).&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Static Pages
&lt;/h3&gt;

&lt;p&gt;Generated style guides are incredibly useful for visual testing. They remove much of the dynamic nature of sites and replace them with predictable and reliable pages.&lt;/p&gt;

&lt;p&gt;Tools like &lt;a href=""&gt;Storybook&lt;/a&gt; have made a ton of progress in getting style guides/pattern libraries set up. Sure, you're not testing the actual site, but it's certainly helping the cause.&lt;/p&gt;

&lt;p&gt;Testing your components in isolation and succeeding is much better than trying to test everything allat once and constantly failing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use better algorithms
&lt;/h3&gt;

&lt;p&gt;This is the "you get what you pay for" section. Open-source tools are neat, but I haven't found one that offers what paid tools can provide (I'm always open to suggestions though).&lt;/p&gt;

&lt;p&gt;There's a myriad of paid tools out there, but I'm going to focus on the two that I have the most experience with here.&lt;/p&gt;

&lt;h4&gt;
  
  
  Percy
&lt;/h4&gt;

&lt;p&gt;The team at Percy has continuously improved the product over the past three years.&lt;/p&gt;

&lt;p&gt;They've added intelligent features like "screenshot stabilization", which helps remove false positives due to font rendering and animation.&lt;/p&gt;

&lt;p&gt;They've also built out a slick interface for managing screenshots through the software development lifecycle.&lt;/p&gt;

&lt;p&gt;A friendly interface for managing screenshots is not something I've mentioned before, but it's an absolute necessity. It's hard to explain without getting in to too much detail, but a good interface streamlines the complexities of this type of testing.&lt;/p&gt;

&lt;p&gt;Simple demos of can't account for projects that have multiple test environments and multiple code branches going at the same time.&lt;/p&gt;

&lt;p&gt;When you try it in a real environment, you quickly realize that the basic tools aren't functional enough to be manageable long-term (or usable by a wide range of folks).&lt;/p&gt;

&lt;p&gt;And that's where paid tools really pay off and why I recommend you check them out.&lt;/p&gt;

&lt;h4&gt;
  
  
  Applitools
&lt;/h4&gt;

&lt;p&gt;One alternative to Percy is Applitools, which bills itself as "AI-powered visual testing and monitoring". The AI part comes to play in the way they manage their image comparison.&lt;/p&gt;

&lt;p&gt;Instead of blindly (heh) comparing the before and after screenshots, their code  intelligently understands different types of changes.&lt;/p&gt;

&lt;p&gt;Have a component that has different text, but the same layout? You can define that as a 'Layout match level', which allows for different text as long as the general geometry of the area is the same.&lt;/p&gt;

&lt;p&gt;That's super helpful if you don't have complete control over the text shown on the site.&lt;/p&gt;

&lt;p&gt;And like Percy, they also provide a hosted dashboard of test results for you, which again, is essential in any solution. &lt;/p&gt;

&lt;p&gt;Along with that, they've also done a lot of work to integrate with tools out there like Storyboard and test frameworks.&lt;/p&gt;

&lt;p&gt;They've put in a ton of work into their product so you don't have to. Why not take advantage of that?&lt;/p&gt;

&lt;h2&gt;
  
  
  Not so stupid after all
&lt;/h2&gt;

&lt;p&gt;I stated at the beginning that I think Visual Regression Testing is stupid. I still believe that.&lt;/p&gt;

&lt;p&gt;But it doesn't have to be. I write this as a reality check, rather than a condemnation.&lt;/p&gt;

&lt;p&gt;Just because I believe it's "stupid" doesn't mean it can't be smart.&lt;/p&gt;

&lt;p&gt;Just as web frameworks and programming languages have improved tremendously over time, visual regression tooling is doing the same.&lt;/p&gt;

&lt;p&gt;Please, do add visual regression testing to your testing suites, it's incredibly powerful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But be aware that the basic functionality won't be enough for professional use.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll need to add some intelligence to your process.&lt;/p&gt;

&lt;p&gt;Give those quick-start tutorials a try, but also put in the extra work to make the testing effective.&lt;/p&gt;

&lt;p&gt;Don't give up when the first attempts are a bit too bumpy for your needs.&lt;/p&gt;

&lt;p&gt;Find ways to smooth out the process by simplifying your scenarios. Look in to paid solutions that offer functionality not available yet in the open-source world.&lt;/p&gt;

&lt;p&gt;And understand that while it can make testing appear easier, website testing is, and always will be, a complex process that requires a little brainpower.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I have done paid work for Applitools in the past, but they are in no way compensating me in writing this.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>webdev</category>
      <category>coding</category>
    </item>
    <item>
      <title>Stop! Don't test that!</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Thu, 11 Oct 2018 18:22:55 +0000</pubDate>
      <link>https://forem.com/klamping/stop-dont-test-that-21hh</link>
      <guid>https://forem.com/klamping/stop-dont-test-that-21hh</guid>
      <description>&lt;p&gt;It's safe to say that testing in the front-end world has grown over the past five years.&lt;/p&gt;

&lt;p&gt;Jest has stolen the scene in the unit testing world, earning over 20,000 stars on Github and being the subject of many popular conference talks.&lt;/p&gt;

&lt;p&gt;On the other side, tools like WebdriverIO, Protractor and Cypress.io are popularizing the concept of UI testing.&lt;/p&gt;

&lt;p&gt;There are more options than ever for writing tests, and more pressure than ever to have bug-free code.&lt;/p&gt;

&lt;p&gt;So why in world would you not write tests?&lt;/p&gt;

&lt;h2&gt;
  
  
  User testing comes first
&lt;/h2&gt;

&lt;p&gt;There's no point in writing a test if you haven't user tested your site.&lt;/p&gt;

&lt;p&gt;When starting clean on a new project, it's incredibly tempting to commit to testing from the beginning. But the most important testing we can start with is user validation of the functionality.&lt;/p&gt;

&lt;p&gt;Any test you write will be worthless when the functionality shifts, and it will after user feedback.&lt;/p&gt;

&lt;p&gt;So before spending time writing assertions, test your assumptions about the user interaction on your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unclear Architecture
&lt;/h2&gt;

&lt;p&gt;The front-end world is rapidly changing with new libraries popping up on a daily basis.&lt;/p&gt;

&lt;p&gt;This leaves many of us starting projects utilizing tools we've never used before.&lt;/p&gt;

&lt;p&gt;Writing tests in Jest is not trivial. Especially when starting out. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do mocks work?&lt;/li&gt;
&lt;li&gt;What's shallow rendering?&lt;/li&gt;
&lt;li&gt;Do I mock or do I import?&lt;/li&gt;
&lt;li&gt;Should I use Enzyme and Puppeteer and CICD and so on?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's impossible to answer these questions when you're this fresh to a library.&lt;/p&gt;

&lt;p&gt;Instead, take some time to learn what the architecture really looks like. Give yourself permission to write untested code.&lt;/p&gt;

&lt;p&gt;Assume you'll be more effective waiting on tests than trying to jam them in up-front.&lt;/p&gt;

&lt;h2&gt;
  
  
  Opportunity Cost
&lt;/h2&gt;

&lt;p&gt;You're not paid to write tests. Tests only serve the application they're testing. If app is useless, tests won't help.&lt;/p&gt;

&lt;p&gt;If you're working on a side project for a tool that no one uses, spending time writing tests takes away from time spent on more important tasks, like getting people to use your work.&lt;/p&gt;

&lt;p&gt;Users don't care whether you have good unit tests. There's no difference between an unused tool and an unused unit tested tool.&lt;/p&gt;

&lt;p&gt;Let yourself have untested code. Worry about that problem when it actually becomes one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finish the system
&lt;/h2&gt;

&lt;p&gt;Don't write more tests when you're not using the ones you have.&lt;/p&gt;

&lt;p&gt;If you have 500 unit tests, but never put in the time to integrate them in your build and deployment process, you have 500 useless tests. Writing 500 more won't help.&lt;/p&gt;

&lt;p&gt;Your tests should run on every code push. They should run before every deploy. Every developer on the team should see that the tests passed or failed.&lt;/p&gt;

&lt;p&gt;If that's not true, then you shouldn't be writing more tests. You should be taking advantage of the tests you have. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why test then?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.kevinlamping.com/this-is-why-you-should-unit-test/"&gt;Testing is incredibly useful&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;They can prevent many stupid little mistakes from making it to production.&lt;/p&gt;

&lt;p&gt;They can guide your coding process, helping your write better code.&lt;/p&gt;

&lt;p&gt;But there's no good way around the effort tests take to write.&lt;/p&gt;

&lt;p&gt;So ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are unit/UI tests really what's most important at this time?&lt;/li&gt;
&lt;li&gt;Is the project in a good spot for writing them?&lt;/li&gt;
&lt;li&gt;Are we using the tests we already have?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be honest with yourself and your project.&lt;/p&gt;

&lt;p&gt;Tests are like a garden. Don't try planting in the middle of winter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Header Photo by &lt;a href="https://unsplash.com/photos/HBABoZYH0yI?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Isaiah Rustad&lt;/a&gt; on &lt;a href="https://unsplash.com/search/photos/stop?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Converting 'Yes'/'No' value to true/false in assertions</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Wed, 10 Oct 2018 01:11:55 +0000</pubDate>
      <link>https://forem.com/klamping/converting-yesno-value-to-truefalse-in-assertions-46be</link>
      <guid>https://forem.com/klamping/converting-yesno-value-to-truefalse-in-assertions-46be</guid>
      <description>&lt;p&gt;I recently wrote a test which required comparing a "Yes/No" displayed value to a true/false database value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftansx2adnfozdhausxj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftansx2adnfozdhausxj4.png"&gt;&lt;/a&gt;&lt;/p&gt;
Example HTML table mapping to the Database Schema.



&lt;p&gt;It wasn't a completely trivial task, so I decided to share the solution I came up with.&lt;/p&gt;

&lt;p&gt;This example uses &lt;a href="https://www.chaijs.com/api/bdd/" rel="noopener noreferrer"&gt;Chai's 'expect' assertion syntax&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's my initial attempt at it, &lt;strong&gt;which is incomplete for reasons I'll go into next.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.is-allowed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns 'Yes'&lt;/span&gt;

&lt;span class="c1"&gt;// pretend 'db' is some magic database call that's all wired up&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;databaseValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isAllowed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns true&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayedValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;databaseValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Displayed value matches database&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty good, but won't catch issues in the display value if the &lt;code&gt;databaseValue&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, if our &lt;code&gt;isAllowed&lt;/code&gt; database value is &lt;code&gt;false&lt;/code&gt;, then anything other than 'Yes' in that displayed value will result in a passing test (e.g. an invalid value that's misspelled, like 'Yess', would still pass).&lt;/p&gt;

&lt;p&gt;Instead, here's a more resilient variation, where we validate that the text is either 'Active' or 'Inactive' depending on the database value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns 'Inactive'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;databaseValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isActive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns false&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayedValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Inactive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version helps lock down the possible allowed values being displayed. It only passes if the exact text matches for either database value.&lt;/p&gt;

&lt;p&gt;Notice we also don't need to add an assertion message, as the values we're passing in are all the information we need.&lt;/p&gt;

&lt;p&gt;If you're unfamiliar with the ternary statement at the end, check out &lt;a href="https://scotch.io/tutorials/understand-the-javascript-ternary-operator-like-abc#toc-ternary-operator" rel="noopener noreferrer"&gt;this insightful post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Header Photo by &lt;a href="https://unsplash.com/photos/qAZO-wu3tik?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jon Tyson&lt;/a&gt; on &lt;a href="https://unsplash.com/search/photos/yes?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>coding</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to test that login page of yours</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Mon, 06 Aug 2018 21:48:59 +0000</pubDate>
      <link>https://forem.com/klamping/how-to-test-that-login-page-of-yours-1bpe</link>
      <guid>https://forem.com/klamping/how-to-test-that-login-page-of-yours-1bpe</guid>
      <description>&lt;p&gt;"Yeah, I'd love to start testing, but I just don't for some reason".&lt;/p&gt;

&lt;p&gt;I've heard this statement a lot, and have said it myself a few too many times. &lt;/p&gt;

&lt;p&gt;In fact, I wrote about it in a previous post:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/klamping" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32007%2Fe8d792cc-921f-4e2a-979c-e2060360c382.jpeg" alt="klamping"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/klamping/why-youre-not-writing-ui-tests-5fdd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Why You're Not Writing UI Tests&lt;/h2&gt;
      &lt;h3&gt;Kevin Lamping ・ May 18 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#agile&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;While there are plenty of tutorials out there on how to write a basic automated test, they don't seem to get people past that initial resistance.&lt;/p&gt;

&lt;p&gt;They're just a too simple of examples to really apply in to a real website. Questions like "What should I be checking?" and "how do I organize this?" usually keep folks from moving forward.&lt;/p&gt;

&lt;p&gt;So I had an idea: What if I put together a set of tests for devs so they get that first step out of the way?&lt;/p&gt;

&lt;p&gt;What if someone could go to a site, answer a few prompts, and be given a set of tests to get them started?&lt;/p&gt;

&lt;p&gt;I thought that'd be really cool!&lt;/p&gt;

&lt;h1&gt;
  
  
  Identifying a starting point
&lt;/h1&gt;

&lt;p&gt;In order to do this, I needed a common bit of functionality that almost all websites shared.&lt;/p&gt;

&lt;p&gt;What's one thing almost all websites have? A login form.&lt;/p&gt;

&lt;p&gt;So I threw together a landing page where people could sign up for updates, then I let the idea percolate a little (really, I was just too busy making the video tutorials to dedicate time to the idea). A few folks signed up, which was enough to show me that people were interested in the idea.&lt;/p&gt;

&lt;p&gt;I finally got around to building out the functionality and put together the website &lt;a href="https://testyourlog.in" rel="noopener noreferrer"&gt;https://testyourlog.in&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey8mpj5jias25arl7mww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey8mpj5jias25arl7mww.png" alt="Test Your Login Homepage" width="663" height="813"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go give it shot and let me know if it helps. I'd love to have your feedback.&lt;/p&gt;

&lt;p&gt;If you want, you can just go to there and ignore the rest of this post.&lt;/p&gt;

&lt;p&gt;But if you want to know the details, here's a full, in-depth tutorial on how to write tests for your login page.&lt;/p&gt;

&lt;h1&gt;
  
  
  The "Test your Login" WebdriverIO Tutorial
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Video Version
&lt;/h2&gt;

&lt;p&gt;I did a YouTube live stream a while back, and if you prefer video format (like me), perhaps you'll fancy the video tutorial better than the text below. Or you can go with both!&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dl-YnA_njXo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The Text Version
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install WebdriverIO
&lt;/h3&gt;

&lt;p&gt;If you haven't messed around with &lt;a href="https://webdriver.io" rel="noopener noreferrer"&gt;WebdriverIO&lt;/a&gt;, I'll quickly explain that it's a functional test automation framework. It allows you to script out page actions to take in a browser, and validate that the actions had the desired affect.&lt;/p&gt;

&lt;p&gt;There are lots of reasons I love WebdriverIO, but I cover them in another post:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/klamping" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32007%2Fe8d792cc-921f-4e2a-979c-e2060360c382.jpeg" alt="klamping"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/klamping/how-webdriverio-makes-testing-worth-it" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How WebdriverIO makes testing worth it&lt;/h2&gt;
      &lt;h3&gt;Kevin Lamping ・ Sep 4 '17&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Before I get to installing WebdriverIO, you need to have a recent version NodeJS and be in an NPM package.&lt;/p&gt;

&lt;p&gt;I won't cover the first item (it varies greatly by system and there are plenty of tutorials out there already), but if you aren't in an NPM package, you can quickly set one up by opening up a command prompt and running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So long as you have those two things, you can install WebdriverIO by running &lt;a href="https://docs.npmjs.com/getting-started/installing-npm-packages-locally" rel="noopener noreferrer"&gt;the normal NPM command for such things&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;--save-dev&lt;/span&gt; webdriverio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Running WebdriverIO
&lt;/h3&gt;

&lt;p&gt;I used to recommend folks &lt;a href="https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/" rel="noopener noreferrer"&gt;add a command to their &lt;code&gt;package.json&lt;/code&gt; scripts section&lt;/a&gt;, but now I go with a much simpler solution, &lt;a href="https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b" rel="noopener noreferrer"&gt;npx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can run the WebdriverIO CLI with just:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx wdio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;The first time you run that command, it will check for a &lt;code&gt;wdio.conf.js&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;Since we haven't created one yet, WebdriverIO is smart enough to figure that out and help us through the process. Here are the answers I chose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where do you want to execute your tests? &lt;strong&gt;On my local machine&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Which framework do you want to use? &lt;strong&gt;mocha&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Shall I install the framework adapter for you? &lt;strong&gt;Yes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Where are your test specs located? &lt;strong&gt;./test/**/*.js&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Which reporter do you want to use?  &lt;strong&gt;spec - &lt;a href="https://github.com/webdriverio/wdio-spec-reporter" rel="noopener noreferrer"&gt;https://github.com/webdriverio/wdio-spec-reporter&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Shall I install the reporter library for you? &lt;strong&gt;Yes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Do you want to add a service to your test setup?  &lt;strong&gt;selenium-standalone - &lt;a href="https://github.com/webdriverio/wdio-selenium-standalone-service" rel="noopener noreferrer"&gt;https://github.com/webdriverio/wdio-selenium-standalone-service&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Shall I install the services for you? &lt;strong&gt;Yes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Level of logging verbosity &lt;strong&gt;silent&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In which directory should screenshots gets saved if a command fails? &lt;strong&gt;./errorShots/&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;What is the base url? &lt;strong&gt;&lt;a href="http://testyourlog.in/example" rel="noopener noreferrer"&gt;http://testyourlog.in/example&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg110rd1xx16bax7hvpb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg110rd1xx16bax7hvpb.gif" alt="Console output when filling out the configurations" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll probably want to replace the test URL with whatever page you want to validate.&lt;/p&gt;

&lt;p&gt;After that last question, WebdriverIO will install our dependencies and generate our configuration file. We still have a few more steps to go for our first test though.&lt;/p&gt;
&lt;h3&gt;
  
  
  Folder &amp;amp; File set up
&lt;/h3&gt;

&lt;p&gt;We told WebdriverIO that we've got our tests stored in the &lt;code&gt;test&lt;/code&gt; folder. Go ahead and create that folder if you haven't already. Then, create a file called &lt;code&gt;login.js&lt;/code&gt; and open it up in your favorite text editor. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujxk2zokvshv0pc8wd7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujxk2zokvshv0pc8wd7r.png" alt="Folder/File Overview" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebdriverIO can be set up to use Mocha, which is what I did in my configuration answers earlier. This helps organize our tests and process the test results.&lt;/p&gt;

&lt;p&gt;Mocha uses two functions, &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;it&lt;/code&gt;, to add hierarchy to test suites. If you're unfamiliar with them, &lt;a href="https://mochajs.org/#getting-started" rel="noopener noreferrer"&gt; check out the official docs&lt;/a&gt; and my take on them:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/klamping" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32007%2Fe8d792cc-921f-4e2a-979c-e2060360c382.jpeg" alt="klamping"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/klamping/take-a-drive-with-webdriverio-and-mocha-14e" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Take a Drive with WebdriverIO and Mocha&lt;/h2&gt;
      &lt;h3&gt;Kevin Lamping ・ Dec 11 '17&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;For our needs, we'll set up the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login Page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should let you log in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// our tests will go here&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You do need both &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;it&lt;/code&gt;, as that's the hierarchy Mocha excepts. The &lt;code&gt;it&lt;/code&gt; goes inside the &lt;code&gt;describe&lt;/code&gt; block. Inside of the &lt;code&gt;it&lt;/code&gt; block we'll put our tests.&lt;/p&gt;
&lt;h2&gt;
  
  
  All set up and ready to dance
&lt;/h2&gt;

&lt;p&gt;Okay, we've got WebdriverIO configured and our test file laid out. Let's write our first test.&lt;/p&gt;

&lt;p&gt;We're checking out a basic "happy path" scenario: The user enters in valid credentials for an active account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7m033185w7b1102h26o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7m033185w7b1102h26o.gif" alt="Showing logging in" width="575" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are four unique steps to this test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the login page&lt;/li&gt;
&lt;li&gt;Enter valid credentials&lt;/li&gt;
&lt;li&gt;Click submit&lt;/li&gt;
&lt;li&gt;Validate we're logged in&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's go through these one at a time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Going to the login page
&lt;/h3&gt;

&lt;p&gt;The basic way to move to various pages in WebdriverIO is to use &lt;a href="http://webdriver.io/api/protocol/url.html" rel="noopener noreferrer"&gt;the &lt;code&gt;url&lt;/code&gt; command&lt;/a&gt;. If you pass in text to it, WebdriverIO will tell the browser to that specific webpage.&lt;/p&gt;

&lt;p&gt;You could pass in the entire URL of the page you want to test, but since we've already defined the domain we're testing on (see config generation above), all we have to pass in is the path. &lt;/p&gt;

&lt;p&gt;That looks like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should let you log in', function () {
  browser.url('./');
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The path you use will depend on where your login page lives. Maybe it's part of your homepage (like ours is). Maybe it's some complex URL that users have no hope of remembering.&lt;/p&gt;

&lt;p&gt;Whatever it is, just use the right one :)&lt;/p&gt;
&lt;h3&gt;
  
  
  Entering valid credentials
&lt;/h3&gt;

&lt;p&gt;Now that we're on our login page with our login form, we need to enter our username/email and password.&lt;/p&gt;

&lt;p&gt;The command we need to use for this is called &lt;a href="http://webdriver.io/api/action/setValue.html" rel="noopener noreferrer"&gt;'setValue'&lt;/a&gt;. It works by accepting &lt;a href="http://webdriver.io/guide/usage/selectors.html" rel="noopener noreferrer"&gt;an element selector&lt;/a&gt; and a text value to insert in said element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should let you log in', function () {
  browser.url('/');
  browser.setValue('input[name="email"]', 'valid@user.com');
  browser.setValue('input[name="password"]', 'hunter2');
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For our element selectors, we use a combination of an HTML element and an HTML attribute. If you're not familiar with &lt;a href="http://blog.kevinlamping.com/selecting-elements-in-webdriverio/" rel="noopener noreferrer"&gt;selecting elements in WebdriverIO&lt;/a&gt;, you're definitely going to want to read up on it.&lt;/p&gt;

&lt;p&gt;Again, update your selectors and credentials with what's right for your site. &lt;/p&gt;
&lt;h3&gt;
  
  
  Clicking Submit
&lt;/h3&gt;

&lt;p&gt;Okay, we've gone to the login page and have entered our credentials. Let's finish logging in.&lt;/p&gt;

&lt;p&gt;There is a 'submitForm' command, but it's been deprecated, so we'll just go with clicking the 'Login' button.&lt;/p&gt;

&lt;p&gt;We can 'click' and element by using &lt;a href="http://webdriver.io/api/action/click.html" rel="noopener noreferrer"&gt;the &lt;code&gt;click&lt;/code&gt; command&lt;/a&gt;. That just makes sense, right?&lt;/p&gt;

&lt;p&gt;All we need to do beyond calling the command is pass in a selector defining what element we want to click. This will trigger Webdriver to simulate a mouse left click in the center of that element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should let you log in', function () {
  browser.url('/');
  browser.setValue('input[name="email"]', 'valid@user.com');
  browser.setValue('input[name="password"]', 'hunter2');
  browser.click('.button=Login');
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Woah, what is that &lt;code&gt;=login&lt;/code&gt; selector?! Turns out, &lt;a href="http://webdriver.io/guide/usage/selectors.html#Element-with-certain-text" rel="noopener noreferrer"&gt;you can select elements by the text those elements contain&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;WebdriverIO is so cool.&lt;/p&gt;
&lt;h3&gt;
  
  
  Validating we're logged in
&lt;/h3&gt;

&lt;p&gt;If all has gone well, we should be logged in now. But how do we really know?&lt;/p&gt;

&lt;p&gt;If we were to run our test, the login page would quickly flash by, and we may miss visually verifying things worked out as planned.&lt;/p&gt;

&lt;p&gt;Instead, we're going to use 'assertions' to check the status for us.&lt;/p&gt;

&lt;p&gt;The simplest way I know to explain assertions is to say that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You give the computer some unknown value (like a variable)&lt;/li&gt;
&lt;li&gt;You give the computer a known value (like the number 9)&lt;/li&gt;
&lt;li&gt;You tell the computer to validate the relationship between those two values. Examples:

&lt;ul&gt;
&lt;li&gt;The variable should equal 9&lt;/li&gt;
&lt;li&gt;The variable should not equal 9&lt;/li&gt;
&lt;li&gt;The variable should be bigger than 9&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the value of the variable is 8, only the second assertion will pass (8 does not equal 9). &lt;/p&gt;

&lt;p&gt;Usually the variable is the result of some code function you want to test. Maybe you have a function that calculates the square of a number (called &lt;code&gt;calcSquare&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Your assertions would be:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert.equal(calcSquare(3), 9); // 9 == 9
assert.notEqual(calcSquare(2), 9); // 4 != 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Both of those assertions will pass, assuming the &lt;code&gt;calcSquare&lt;/code&gt; function is working correctly.&lt;/p&gt;

&lt;p&gt;We can use assertions in many ways in WebdriverIO. For our current needs, we want to validate that the url of the page we're on is either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;not the same as the login url&lt;/li&gt;
&lt;li&gt;the same as the url after logging in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first is a more general test, and may result in a false positive (the test passes when it shouldn't) if the login takes you to a different page without logging you in (for example, a 'forgot your password' page).&lt;/p&gt;

&lt;p&gt;The second option is a better one, but requires knowing the url of the page you get logged in to. &lt;/p&gt;

&lt;p&gt;Thankfully, I know that URL for my example. But just in case, I'll show you both assertions.&lt;/p&gt;

&lt;p&gt;First, we need to get the URL of the page we're now on (Webdriver is smart enough to wait for the page to reload after submitting the login form). &lt;/p&gt;

&lt;p&gt;We get that url with &lt;a href="http://webdriver.io/api/property/getUrl.html" rel="noopener noreferrer"&gt;the &lt;code&gt;getUrl&lt;/code&gt; command&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should let you log in', function () {
  browser.url('/');
  browser.setValue('input[name="email"]', 'valid@user.com');
  browser.setValue('input[name="password"]', 'hunter2');
  browser.click('.button=Login');

  const pageUrl = browser.getUrl();
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We don't pass any value in to the &lt;code&gt;getUrl&lt;/code&gt; command. We simply assign the result of it to a &lt;code&gt;pageUrl&lt;/code&gt; constant. &lt;/p&gt;

&lt;p&gt;With it, we can now run our assertions:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should let you log in', function () {
  browser.url('/');
  browser.setValue('input[name="email"]', 'valid@user.com');
  browser.setValue('input[name="password"]', 'hunter2');
  browser.click('.button=Login');

  const pageUrl = browser.getUrl();
  assert.notEqual(pageUrl, 'http://testyourlog.in/example/');
  assert.equal(pageUrl, 'http://testyourlog.in/example/logged-in.html?email=valid%40user.com&amp;amp;password=hunter2');
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I include both assertion types here, but you should really only need to include one.&lt;/p&gt;

&lt;p&gt;Wait.&lt;/p&gt;

&lt;p&gt;Where did this magical &lt;code&gt;assert&lt;/code&gt; come from? &lt;/p&gt;

&lt;p&gt;Nowhere, yet!&lt;/p&gt;

&lt;p&gt;Yes, I neglected to mention the minor detail of loading &lt;a href="https://nodejs.org/api/assert.html" rel="noopener noreferrer"&gt;Node's 'assert' library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thankfully that is pretty easy. Just shoot up to the top of your file and add:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now you're ready to party.&lt;/p&gt;

&lt;p&gt;Here's the full script just for easier reference:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const assert = require('assert');

describe('Login Page', function () {
  it('should let you log in', function () {
    browser.url('/');
    browser.setValue('input[name="email"]', 'valid@user.com');
    browser.setValue('input[name="password"]', 'hunter2');
    browser.click('.button=Login');

    const pageUrl = browser.getUrl();
    assert.notEqual(pageUrl, 'http://testyourlog.in/example/');
    assert.equal(pageUrl, 'http://testyourlog.in/example/logged-in.html?email=valid%40user.com&amp;amp;password=hunter2');
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's run our tests already!
&lt;/h2&gt;

&lt;p&gt;We've got our test written and our assertions in place. Time to try it all out.&lt;/p&gt;

&lt;p&gt;In a terminal window (or command prompt if you prefer to call it that), run your &lt;code&gt;npx wdio&lt;/code&gt; command again.&lt;/p&gt;

&lt;p&gt;If everything is set up correctly, you will see a Firefox browser momentarily pop up on your screen.&lt;/p&gt;

&lt;p&gt;Hopefully your test completed and passed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo1yzw57j3wqk6ypccl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo1yzw57j3wqk6ypccl5.png" alt="Console output of successful test passing" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  That's it for now
&lt;/h2&gt;

&lt;p&gt;There's more to test on our login page and we'll also want to try out using Page Objects. But this is about all I can type on the subject for now (and probably all you have time to read).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://testyourlog.in/" rel="noopener noreferrer"&gt;The official testyourlog.in generator&lt;/a&gt; includes visual regression testing, TravisCI integration and Page Object support, which are all advanced subjects.&lt;/p&gt;

&lt;p&gt;I cover all these subjects out on &lt;a href="https://www.youtube.com/user/medigerati/" rel="noopener noreferrer"&gt;my free YouTube channel&lt;/a&gt; and in &lt;a href="https://learn.webdriver.io" rel="noopener noreferrer"&gt;my special videos tutorials on WebdriverIO&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're interested in seeing the code that runs testyourlog.in, it's available via GitHub:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/klamping" rel="noopener noreferrer"&gt;
        klamping
      &lt;/a&gt; / &lt;a href="https://github.com/klamping/testyourlog.in" rel="noopener noreferrer"&gt;
        testyourlog.in
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A tool to auto-generate a WebdriverIO script to test your login/registration forms
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;testyourlog.in&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;A tool to auto-generate a WebdriverIO script to test your login/registration forms&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/klamping/testyourlog.in" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>testing</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Stop lying to yourself when testing</title>
      <dc:creator>Kevin Lamping</dc:creator>
      <pubDate>Tue, 24 Jul 2018 17:27:34 +0000</pubDate>
      <link>https://forem.com/klamping/stop-lying-to-yourself-when-testing-42bk</link>
      <guid>https://forem.com/klamping/stop-lying-to-yourself-when-testing-42bk</guid>
      <description>&lt;p&gt;&lt;a href="http://www.nytimes.com/interactive/2015/07/03/upshot/a-quick-puzzle-to-test-your-problem-solving.html"&gt;The New York Times had a quiz a while back&lt;/a&gt; with a simple task: figure out the mathematical rule behind a sequence of numbers.&lt;/p&gt;

&lt;p&gt;As a reader, you would enter your own numbers and see if they pass or fail your guess at the rule.&lt;/p&gt;

&lt;p&gt;In my mind, this is very similar to the way we unit test. Provide an input, validate the output. Here, you provide the input (the numbers), and the output is whether the number sequence matches the rule.&lt;/p&gt;

&lt;p&gt;You can imagine the unit test for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;checkRule&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// some magical formula we’re supposed to figure out&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my mathematical equation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should pass when doubling each number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkRule&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toBeTrue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkRule&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toBeTrue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkRule&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toBeTrue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkRule&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toBeTrue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at this code, it’s easy to assume that the rule is “Each number should double the previous one”. After all, our four assertions pass, so we’ve got green tests!&lt;/p&gt;

&lt;p&gt;The trick with the quiz is that the mathematical equation is very simple: each number must be larger than the previous one.&lt;/p&gt;

&lt;p&gt;This broad rule means that it’s easy for people to assume their complex solution is the correct one. Every input they give to validate their rule returns true, so it must be right.&lt;/p&gt;

&lt;p&gt;Yet there’s a flaw to this testing methodology, as the article points out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remarkably, 78 percent of people who have played this game so far have guessed the answer without first hearing a single no. A mere 9 percent heard at least three nos — even though there is no penalty or cost for being told no, save the small disappointment that every human being feels when hearing “no.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The article attributes this as “&lt;a href="http://rationalwiki.org/wiki/Confirmation_bias"&gt;confirmation bias&lt;/a&gt;” which partially applies. But a better description is &lt;a href="http://rationalwiki.org/wiki/List_of_cognitive_biases"&gt;a lesser known bias&lt;/a&gt; called Congruence Bias. (one I was unaware of before hearing about this article on &lt;a href="http://www.theskepticsguide.org/"&gt;The Skeptic’s Guide to the Universe&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This bias is “the tendency to test hypotheses exclusively through direct testing, in contrast to tests of possible alternative hypotheses.”&lt;/p&gt;

&lt;p&gt;In our tests above, we’re only checking for positive results. We never ask “does this fail if I provide data which contradicts the rule?” &lt;/p&gt;

&lt;p&gt;Every suite of unit tests should have negation checks. A simple &lt;code&gt;expect(passesRule([2,4,6])).toNotBeTrue;&lt;/code&gt; would have broken our tests, showing us that the rule passes despite 6 not being twice that of 4. &lt;/p&gt;

&lt;p&gt;Again, from the article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you want to test a theory, don’t just look for examples that prove it. When you’re considering a plan, think in detail about how it might go wrong.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That second part rings especially true for testing.&lt;/p&gt;

&lt;p&gt;It’s easy to assume that because your tests pass, the code and the tests are working as expected. But we must remember &lt;a href="https://en.wikiquote.org/wiki/Edsger_W._Dijkstra#1960s"&gt;what Edsger Dijkstra said long ago&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Testing shows the presence, not the absence of bugs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think about confirmation and congruence bias next time you’re testing your code.&lt;/p&gt;

&lt;p&gt;Keep in mind the phrase “fail fast”. Prove that your code really is what it says it is and always keep a skeptical mind when coding.&lt;/p&gt;

&lt;p&gt;Don’t wait until it’s too late to learn the harsh truth.&lt;/p&gt;

&lt;p&gt;In &lt;a href="http://neurotheory.columbia.edu/~ken/cargo_cult.html"&gt;the words of Richard Feynman&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The first principle is that you must not fool yourself — and you are the easiest person to fool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For more analysis of the quiz itself, and thoughts on congruence bias, check out these discussions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.sgutranscripts.org/wiki/SGU_Episode_361#Congruence_Bias_.2853:19.29"&gt;SGU Transcript&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://theness.com/neurologicablog/index.php/a-quick-logic-lesson/"&gt;Neurological blog post about it&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Header Photo by &lt;a href="https://unsplash.com/photos/3y1zF4hIPCg"&gt;Hans-Peter Gauster&lt;/a&gt; on &lt;a href="https://unsplash.com/"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>coding</category>
      <category>testing</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
