Wednesday, August 10, 2016

How to Customize the Menu Bar With BitBar

New Coffee Break Course: Best Practices for Building Actions

Illustrator in 60 Seconds: How to Create an Avatar Icon

Inspiration: Online Stores Where Products Are Placed Front and Center

Building a Simple Shopify App

Google Play Services: Awareness API

15 Best WordPress Event Themes: For Conferences and More

Adding Custom Hooks in WordPress: Custom Actions

How to Create a Spiderman Inspired Text Effect in Adobe Photoshop

How To Get Started with Photo Mechanic: 3 Essential Workflows

How to Plan Your Travel Assignment

Tuesday, August 9, 2016

How to Become a Web Developer: Learn PHP

WooCommerce Grouped Products and Product Attributes: Deciding Which to Use

How to Create a Game Boy Illustration Using Adobe Illustrator

Android From Scratch: Creating Styles and Themes

How to Use Map, Filter, & Reduce in JavaScript

How to Use Map, Filter, & Reduce in JavaScript

Functional programming has been making quite a splash in the development world these days. And for good reason: Functional techniques can help you write more declarative code that is easier to understand at a glance, refactor, and test. 

One of the cornerstones of functional programming is its special use of lists and list operations. And those things are exactly what the sound like they are: arrays of things, and the stuff you do to them. But the functional mindset treats them a bit differently than you might expect.

This article will take a close look at what I like to call the "big three" list operations: map, filter, and reduce. Wrapping your head around these three functions is an important step towards being able to write clean functional code, and opens the doors to the vastly powerful techniques of functional and reactive programming.

It also means you'll never have to write a for loop again.

Curious? Let's dive in.

A Map From List to List

Often, we find ourselves needing to take an array and modify every element in it in exactly the same way. Typical examples of this are squaring every element in an array of numbers, retrieving the name from a list of users, or running a regex against an array of strings.

map is a method built to do exactly that. It's defined on Array.prototype, so you can call it on any array, and it accepts a callback as its first argument. 

When you call map on an array, it executes that callback on every element within it, returning a new array with all of the values that the callback returned.

Under the hood, map passes three arguments to your callback:

  1. The current item in the array
  2. The array index of the current item
  3. The entire array you called map on 

Let's look at some code.

map in Practice

Suppose we have an app that maintains an array of your tasks for the day. Each task is an object, each with a name and duration property:

Let's say we want to create a new array with just the name of each task, so we can take a look at everything we've gotten done today. Using a for loop, we'd write something like this:

JavaScript also offers a forEach loop. It functions like a for loop, but manages all the messiness of checking our loop index against the array length for us:

Using map, we can write:

I include the index and  array parameters to remind you that they're there if you need them. Since I didn't use them here, though, you could leave them out, and the code would run just fine.

There are a few important differences between the two approaches:

  1. Using map, you don't have to manage the state of the for loop yourself.
  2. You can operate on the element directly, rather than having to index into the array.
  3. You don't have to create a new array and push into it. map returns the finished product all in one go, so we can simply assign the return value to a new variable.
  4. You do have to remember to include a return statement in your callback. If you don't, you'll get a new array filled with undefined

Turns out, all of the functions we'll look at today share these characteristics.

The fact that we don't have to manually manage the state of the loop makes our code simpler and more maintainable. The fact that we can operate directly on the element instead of having to index into the array makes things more readable. 

Using a forEach loop solves both of these problems for us. But map still has at least two distinct advantages:

  1. forEach returns undefined, so it doesn't chain with other array methods. map returns an array, so you can chain it with other array methods.
  2. map returns an array with the finished product, rather than requiring us to mutate an array inside the loop. 

Keeping the number of places where you modify state to an absolute minimum is an important tenet of functional programming. It makes for safer and more intelligible code.

Now is also a good time to point out that if you're in Node, testing these examples in the Firefox browser console, or using Babel or Traceur, you can write this more concisely with ES6 arrow functions:

Arrow functions let us leave out the return keyword in one-liners. 

It doesn't get much more readable than that.

Gotchas

The callback you pass to map must have an explicit return statement, or map will spit out an array full of undefined. It's not hard to remember to include a return value, but it's not hard to forget. 

If you do forget, map won't complain. Instead, it'll quietly hand back an array full of nothing. Silent errors like that can be surprisingly hard to debug. 

Fortunately, this is the only gotcha with map. But it's a common enough pitfall that I'm obliged to emphasize: Always make sure your callback contains a return statement!

Implementation

Reading implementations is an important part of understanding. So, let's write our own lightweight map to better understand what's going on under the hood. If you want to see a production-quality implementation, check out Mozilla's polyfill at MDN.

This code accepts an array and a callback function as arguments. It then creates a new array; executes the callback on each element on the array we passed in; pushes the results into the new array; and returns the new array. If you run this in your console, you'll get the same result as before. Just make sure you initialize tasks before you test it out!

While we're using a for loop under the hood, wrapping it up into a function hides the details and lets us work with the abstraction instead. 

That makes our code more declarative—it says what to do, not how to do it. You'll appreciate how much more readable, maintainable, and, erm, debuggable this can make your code.

Filter Out the Noise

The next of our array operations is filter. It does exactly what it sounds like: It takes an array, and filters out unwanted elements.

Like map, filter is defined on Array.prototype. It's available on any array, and you pass it a callback as its first argument. filter executes that callback on each element of the array, and spits out a new array containing only the elements for which the callback returned true.

Also like map, filter passes your callback three arguments:

  1. The current item 
  2. The current index
  3. The array you called filter on

filter in Practice

Let's revisit our task example. Instead of pulling out the names of each task, let's say I want to get a list of just the tasks that took me two hours or more to get done. 

Using forEach, we'd write:

With filter:

Here, I've gone ahead and left out the index and array arguments to our callback, since we don't use them.

Just like map, filter lets us:

  • avoid mutating an array inside a forEach or for loop
  • assign its result directly to a new variable, rather than push into an array we defined elsewhere

Gotchas

The callback you pass to map has to include a return statement if you want it to function properly. With filter, you also have to include a return statement, and you must make sure it returns a boolean value.

If you forget your return statement, your callback will return undefined, which filter will unhelpfully coerce to false. Instead of throwing an error, it will silently return an empty array! 

If you go the other route, and return something that's isn't explicitly true or false, then filter will try to figure out what you meant by applying JavaScript's coercion rules. More often than not, this is a bug. And, just like forgetting your return statement, it'll be a silent one. 

Always make sure your callbacks include an explicit return statement. And always make sure your callbacks in filter return true or false. Your sanity will thank you.

Implementation

Once again, the best way to understand a piece of code is... well, to write it. Let's roll our own lightweight filter. The good folks at Mozilla have an industrial-strength polyfill for you to read, too.

Reducing Arrays

map creates a new array by transforming every element in an array, individually. filter creates a new array by removing elements that don't belong. reduce, on the other hand, takes all of the elements in an array, and reduces them into a single value.

Just like map and filterreduce is defined on Array.prototype and so available on any array, and you pass a callback as its first argument. But it also takes an optional second argument: the value to start combining all your array elements into. 

reduce passes your callback four arguments:

  1. The current value
  2. The previous value 
  3. The current index
  4. The array you called reduce on

Notice that the callback gets a previous value on each iteration. On the first iteration, there is no previous value. This is why you have the option to pass reduce an initial value: It acts as the "previous value" for the first iteration, when there otherwise wouldn't be one.

Finally, bear in mind that reduce returns a single value, not an array containing a single item. This is more important than it might seem, and I'll come back to it in the examples.

reduce in Practice

Since reduce is the function that people find most alien at first, we'll start by walking step by step through something simple.

Let's say we want to find the sum of a list of numbers. Using a loop, that looks like this:

While this isn't a bad use case for forEachreduce still has the advantage of allowing us to avoid mutation. With reduce, we would write:

First, we call reduce on our list of numbers. We pass it a callback, which accepts the previous value and current value as arguments, and returns the result of adding them together.  Since we passed 0 as a second argument to reduce, it'll use that as the value of previous on the first iteration.

If we take it step by step, it looks like this:

Iteration  Previous Current Total
1 0 1 1
2 1 2 3
3 3 3 6
4 6 4 10
5 10 5 15

If you're not a fan of tables, run this snippet in the console:

To recap: reduce iterates over all the elements of an array, combining them however you specify in your callback. On every iteration, your callback has access to the previous value, which is the total-so-far, or accumulated value; the current value; the current index; and the entire array, if you need them.

Let's turn back to our tasks example. We've gotten a list of task names from map, and a filtered list of tasks that took a long time with... well, filter

What if we wanted to know the total amount of time we spent working today?

Using a forEach loop, you'd write:

With reduce, that becomes:

Easy. 

That's almost all there is to it. Almost, because JavaScript provides us with one more little-known method, called reduceRight. In the examples above, reduce started at the first item in the array, iterating from left to right:

reduceRight does the same thing, but in the opposite direction:

I use reduce every day, but I've never needed reduceRight. I reckon you probably won't, either. But in the event you ever do, now you know it's there.

Gotchas

The three big gotchas with reduce are:

  1. Forgetting to return
  2. Forgetting an initial value
  3. Expecting an array when reduce returns a single value

Fortunately, the first two are easy to avoid. Deciding what your initial value should be depends on what you're doing, but you'll get the hang of it quickly.

The last one might seem a bit strange. If reduce only ever returns a single value, why would you expect an array?

There are a few good reasons for that. First, reduce always returns a single value, not always a single number. If you reduce an array of arrays, for instance, it will return a single array. If you're in the habit or reducing arrays, it would be fair to expect that an array containing a single item wouldn't be a special case.

Second, if reduce did return an array with a single value, it would naturally play nice with map and filter, and other functions on arrays that you're likely to be using with it. 

Implementation

Time for our last look under the hood. As usual, Mozilla has a bulletproof polyfill for reduce if you want to check it out.

Two things to note, here:

  1. This time, I used the name accumulator instead of previous. This is what you'll usually see in the wild.
  2. I assign accumulator an initial value, if a user provides one, and default to 0, if not. This is how the real reduce behaves, as well.

Putting It Together: Map, Filter, Reduce, and Chainability

At this point, you might not be that impressed. 

Fair enough: map, filter, and reduce, on their own, aren't awfully interesting. 

After all, their true power lies in their chainability. 

Let's say I want to do the following:

  1. Collect two days' worth of tasks.
  2. Convert the task durations to hours, instead of minutes.
  3. Filter out everything that took two hours or more.
  4. Sum it all up.
  5. Multiply the result by a per-hour rate for billing.
  6. Output a formatted dollar amount.

First, let's define our tasks for Monday and Tuesday:

And now, our lovely-looking transformation:

Or, more concisely:

If you've made it this far, this should be pretty straightforward. There are two bits of weirdness to explain, though. 

First, on line 10, I have to write:

Two things to explain here:

  1. The plus signs in front of accumulator and current coerce their values to numbers. If you don't do this, the return value will be the rather useless string, "12510075100".
  2. If don't wrap that sum in brackets, reduce will spit out a single value, not an array. That would end up throwing a TypeError, because you can only use map on an array! 

The second bit that might make you a bit uncomfortable is the last reduce, namely:

That call to map returns an array containing a single value. Here, we call reduce to pull out that value.

The other way to do this would be to remove the call to reduce, and index into the array that map spits out:

That's perfectly correct. If you're more comfortable using an array index, go right ahead.

But I encourage you not to. One of the most powerful ways to use these functions is in the realm of reactive programming, where you won't be free to use array indices. Kicking that habit now will make learning reactive techniques much easier down the line.

Finally, let's see how our friend the forEach loop would get it done:

Tolerable, but noisy.

Conclusion & Next Steps

In this tutorial, you've learned how mapfilter, and reduce work; how to use them; and roughly how they're implemented. You've seen that they all allow you to avoid mutating state, which using for and forEach loops requires, and you should now have a good idea of how to chain them all together. 

By now, I'm sure you're eager for practice and further reading. Here are my top three suggestions for where to head next:

  1. Jafar Husain's superb set of exercises on Functional Programming in JavaScript, complete with a solid introduction to Rx.js
  2. Envato Tuts+ Instructor Jason Rhodes' course on Functional Programming in JavaScript
  3. The Mostly Adequate Guide to Functional Programming, which goes into greater depth on why we avoid mutation, and functional thinking in general

JavaScript has become one of the de-facto languages of working on the web. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.

If you want more on this sort of thing, check my profile from time to time; catch me on Twitter (@PelekeS); or hit my blog at http://peleke.me.

Questions, comments, or confusions? Leave them below, and I'll do my best to get back to each one individually.


How to Learn Calligraphy

Start Learning Web Design in 60 Seconds

Photoshop in 60 Seconds: How to Create a Polyscape

Monday, August 8, 2016

How to Reboot Your Brain and Mentally Reset Now

Photography Business to Business: The Doer

How to Create a Stylish 'Save the Date' Card in Adobe InDesign

Get Early Access to Envato Elements—and Lock in a Lifetime Discount

Invisible Forces: Spacing and Shape

Quick Tip: How to Make Changes to Multiple Files Within a Directory Using Python

Quick Tip: How to Make Changes to Multiple Files Within a Directory Using Python

Say that someone is familiar with British spelling and has decided to complete his degree in the US. He is asked to write a paper about Python for the class. He is well versed in Python and has no issue in writing the paper. He was talking about images in a part of his paper and wrote more than once the word grey (British spelling) instead of gray (US spelling), in addition to neighbourhood (British spelling) instead of neighborhood (US spelling). But he is now in the US and has to go through all the words spelled the British way and replace them with the US spellings.

This is one of many scenarios in which we need to change some spelling or mistake in multiple locations. 

In this quick tip, I will show you an example where we have five text files that have misspelled my name. That is, instead of writing Abder, Adber is written. The example will show you how we can use Python to correct the spelling of my name in all the text files included within a directory.

Let's get started!

Data Preparation

Before we move forward with the example, let's prepare the data (text files) we want to work with. Go ahead and download the directory with its files. Unzip the directory and you are now all set.

As you can see, we have a directory named Abder which contains five different files named 1,2,3,4, and 5.

Implementation

Let's get to the fun part. The first thing we need to do is read the content of the directory Abder. For this, we can use the listdir() method, as follows:

If we try to see what's inside the directory, we can do the following:

In which case, we will get:

This shows that we have five rft files inside the directory.

To make sure we are working with the current directory (directory of interest), we can use chdir as follows:

The next thing we need to do is loop through all the files in the directory Abder. We can use a for-loop as follows:

Since we want to look in each of the five files in the directory and look for Adber, the normal thing to do at this stage is to open and read the content of each file:

Now comes a vital step, especially when talking about pattern matching, in our case, searching for Adber. This step is the use of regular expressions. In Python, in order to use regular expressions, we will be using the re module. 

We will be using two main functions from this module. The first is compile():

Compile a regular expression pattern into a regular expression object, which can be used for matching using its match()and search() methods.

And the second is sub(), for substituting the wrong spelling with the correct one. We will thus do the following:

Finally, we want to write the new text after substitution to our files, as follows:

Putting It All Together

In this section, let's see how the whole Python script, which will look for Adber in each file and replace that with Abder, will look:

As we can see, Python makes it very easy to carry out modifications across multiple files using the for-loop. Another important part to remember here is the use of regular expressions for pattern matching. 

If you want to know more about Python's loops, check A Smooth Refresher on Python's Loops. And, for more information about regular expressions, check Regular Expressions in Python.


How to Set Up Your First Online Sales Funnel

Editing Images in CSS: Blend Modes

How to Design a "Match Three" Game Screen in Affinity Designer

Sunday, August 7, 2016

Creating A Deadly Virus Animation in 3ds Max

File Types in Cubase

File Types in Cubase

Introduction

In this tutorial, I'll explian the different file types that Cubase can use and how to employ them to help you in your daily working scenario. You will understand how to import audio from Audio CD, OMFI files, MIDI files, and so on.

In my studio, many clients bring songs and voices recorded onto an Audio CD. Although ripping them into WAV files is a good solution, Cubase offers you with the option to directly import audio from the Audio CD. This way, you can save a lot of time rather than ripping using external software.

In order to do that, go to the File menu and select Audio CD from the Import menu. While Importing an Audio CD, you can specify if you want to import the CD tracks into the pool. This method is useful if you want to import multiple CDs at once into the project.

In the Import Audio from CD window, you have to select the drive that you are going to import the audio data from. This is usually the default CD drive if you have more than one, else select the correct one from the drop-down list.

The track name will be automatically retrieved if the CD is properly labeled or if it is linked to a CD database. If this information is not available in the CD, generic titles will be given to the tracks. You can rename the tracks by double-clicking on the name of the track and typing in the new name.

Sometimes, the CD will be full of scratches and importing the audio will be difficult. You can activate the Secure Mode to scan for errors and corrections on the audio CD. This option takes much more time to process, but will result in an error free and cleaner audio track.

Increasing the Data Transfer Speed will give you a quicker output, but a slower speed will give you an error free extraction. Setting the data transfer speed to a low setting will give you a better output than going for a faster transfer speed.

Activate the checkbox for every file in the CD that you want to import into the project. If you want to copy only a certain part of a file, set the Copy Start and Copy End for the track.

Click the Copy button to create a local copy of the files on your computer. The default format of the files will be .wav (Windows) or .aiff (Mac). The default destination can be changed by clicking on the Destination Folder and selecting the desired folder.

If you want to listen to the track in this stage, click on the Play button to audition the track. After you are done selecting the tracks, click OK and the files will be imported into the project. 

Importing Audio from Video

Although it is possible to import audio from a video by importing the video and then selecting the audio track, for a faster and easier alternative, you can use the Audio from Video option in the Import under File menu. 

You can select the video file that contains the audio that you need and click OK. The rest is just like importing an audio file, you have the option to split the channels or to copy the file to the directory. 

The file will be imported onto the cursor position.

Other Common Formats

Cubase provides you with the option to import REX files as well. REX files are file formats that are created by ReCyle. This software is mainly used to create and edit complex loops easily. Cubase can import .REX or .RX2 files.

To do so, click the Import from File menu and select Audio File. In the file format drop-down menu, select the desired file format. Now Import the file. You can now edit the REX file as you would do in any other software.

OMF files are also supported in Cubase. OMF files lets you use Cubase in sync with other audio and video editing applications. This makes editing of files very easy across various applications. The OMF file can be opened in the required software and edited according to your need.

To export the stereo files in a project, select the OMF file format in the Export option under the File menu. By default, the whole project’s length is exported, if you would like to export only certain parts of the project, set the project locators and the activate the checkbox near the From Left to Right Locator option.

Set the Media Destination Path according to the project folder and then activate the Copy Media so that the media files used in the project will be copied to the same path.

Activating the Consolidate Events option will copy only the files that are being used in the project. Make sure that you leave a few milliseconds of Handle Length so that editing the files later for fades and adjustments will be possible. If this option is not activated, the limited length of the files will not let you adjust the audio length for further editing and crossfades.

Select the file version keeping in mind the format that is supported by the application that you are going to import the OMF file into. OMF 2.0 is supported by the latest versions of almost all professional editing applications.

Another setting that you should consider is the Export All to One File and Export Media File References. The Export All to One File is a very fail-safe method of transferring the files, all the files related to the project will be included in the OMF file. 

The issue with this method is that the file size will be comparatively larger due to the project files being included in the OMF file. If you would like to reduce the size of the OMF file, you can opt for the Export Media File References option. This will only reference the project files and thus reduce the file size greatly. If the media files are not referenced properly, however, files will not be read properly and the whole project could be messed up.

The Export Clip Based Volume, Use Fade Curves, Export Clip Names options are only available with the OMF 2.0 option. These settings help you to export the clip volume, the fades and the file name of the clips as in the project.

The sample size setting is best kept at Same as Project, unless you want to change the sample size to something else. Activate the Quantize Events to Frames so that the clips and events will be adjusted to snap to the frames. 

This setting will help you in syncing the video to the audio if you are working on a film or a similar video project. Importing an OMF file works the same way like exporting the file. Similar options are available and can be adjusted according to the project requirements.

Clean Up

When you work with a lot of takes, sometimes the audio files tend to build up in the system. This can take a lot of hard disk space and can sometimes slow down the project. To remove all these unwanted files, you can use the Cleanup option in the File menu.

Before you start cleaning up, close all open projects in Cubase. Select Cleanup and in the dialog box that appears, select Search Folder and locate the working directory of the project that you want to clean up. You can also scan all your hard disks to find the unused files. Once you’ve selected the required folder or hard disk, click Start.

After the scan has completed, you can select the files one by one by Control-Click or select a group of files by using Shift-Click. You can also select all the files by clicking on the Select All button.

There are a few things that you should keep in mind before you press the Delete button. If you’ve manually renamed the files belonging to a project without syncing it with the project, Cubase considers them as unused files and will list it in the Cleanup list. 

If you’ve put files in a Cubase project folder that is being used in another project, Cubase will consider this file as unused. 

So ensure that you’ve checked all the files that are being used in other projects and reference them accordingly. Remember to see if any of these files are in use by other applications as well.

Once you’ve checked the files for these criteria, click the Delete button and these files be gone from the system forever.

Conclusion

In this tutorial, I've explained the various file types that can be used in Cubase and how to properly import them and use them. The Cleanup option is also a very important function that can help you save tons of hard disk space and help you speed up your system.


Filtering RSS Feeds With Inoreader

Thursday, August 4, 2016

Take a Free Course on JavaScript Refactoring Techniques

How to Create a Time-Displaced Video Effect Like Adele's Send My Love

Amazon Lumberyard: Creating the First 3D Scene

How to Create a Ghosted Dancer Effect in Adobe Photoshop

RSpec Testing for Beginners, Part 1

RSpec Testing for Beginners, Part 1

Are you new to Rails? New to coding? Curious about RSpec and how you can start testing? If so, this article should be a good starting point for you to get into test-driven development. It will explain to you the why and the how, and it will give you a survival kit to go on your first testing spree.

Topics

  • What’s the Point?
  • RSpec?
  • Getting Started
  • Running Tests
  • Basic Syntax
  • Four Phases of Tests
  • The Hard Thing About Testing

What’s the Point?

What is RSpec good for? RSpec is very useful on the Unit Test level, testing the finer details and the business logic of your app. That means testing the internals like models and controllers of your app. Tests that cover your views or feature tests which simulate more complete user flows, like purchasing an item, will not be the focus that RSpec is made for. RSpec does not make use of a web driver—as Capybara does, for example—that simulates a user's interactions with an actual site or a representation of it.

Test-driven development (TDD), what’s the point? Well, that is not that easy to answer without feeding you some clichés. I hope this doesn’t sound evasive. I could provide a quick answer, but I want to avoid sending you home hungry after having only a small snack. The result of this little series about RSpec and testing should not only give you all the info to answer this question yourself but also provide you with the means and the understanding to get started with testing while feeling a bit confident already about the testing thing.

Beginners seem to have a harder time getting into RSpec and the TDD workflow than starting to get dangerous with Ruby or Rails. Why is that? I can only guess at this point, but on the one hand, the literature seems mostly focused on people who already have some programming skills under their belt, and on the other hand, learning all the stuff that is involved to have a clear understanding is a bit daunting. The learning curve can be quite steep, I suppose. For effective testing, there are a lot of moving parts involved. It’s a lot to ask for newbies who have just started to understand a framework like Rails to look at the process of building an app from the opposite perspective and learn a completely new API to write code for your code.

I thought about how to approach this “dilemma” for the next generation of coders who are just looking for a smoother start into this whole thing. This is what I came up with. I will break the most essential syntax down for you without assuming much more than basic knowledge of Ruby and a little bit of Rails. Instead of covering every angle possible and confusing you to death, we will go over your basic survival kit and try to paint the bigger picture. We will discuss the “How?” rather verbosely in order not to lose new coders along the way. The second part of the equation will be explaining the “Why?” 

If I’m lucky, you’ll get away with a good basis for more advanced books while feeling confident about the bigger picture. Ok now, let’s walk the walk! 

Benefits and Such

Let’s get back to the purpose of testing. Is testing useful for writing better quality apps? Well, this can be hotly debated, but at the moment I’d answer this question with a yes—I’m in the hipster TDD camp, I guess. Let’s see why tests provide your apps with a couple of benefits that are hard to ignore:

They check if your work functions as intended. Constantly validating that you are writing code that works is essential to the health of your application and your team’s sanity.

They test stuff you don’t want to test by hand, tedious checks that you could do by hand—especially when you’d need to check this all the time. You want to be as sure as possible that your new function or your new class or whatever does not cause any side effects in maybe completely unforeseen areas of your app. Automating that sort of thing not only saves you a ton of time but will also make testing scenarios consistent and reproducible. That alone makes them much more dependable than error-prone testing by hand.

We want to make sure the app behaves in a certain way, in an expected way. Tests can make sure to a pretty high degree that the way users interact with your app is functioning and avoiding bug scenarios that you were able to foresee. Tests check that your application works the way you designed it—and that it continues to work after you introduce modifications. This is especially important when your test suite informs you about failing scenarios about implementations of your app that might be old and therefore not exactly at the back of your brain anymore and not considered while you introduced some new functionality. In short, it helps to keep your app healthy and avoids introducing tons of bugs.

Automating tests make you actually test more frequently. Imagine if you have to test something for the 40th time for some reason. If it is only a bit time consuming, how easy will it be to get bored and skip the process altogether? These sort of things are the first step on a slippery slope where you can kiss a decent percentage of code coverage goodbye.

Tests work as documentation. Huh? The specs you write give other people on your teams a quick entry point to learn a new code base and understand what it is supposed to do. Writing your code in RSpec, for example, is very expressive and forms highly readable blocks of code that tell a story if done right. Because it can be written very descriptively while also being a very concise Domain Specific Language (DSL), RSpec hits two birds with one stone: not being verbose in its API and providing you with all the means to write highly understandable test scenarios. That’s what I always liked about it and why I never got really warm with Cucumber, which was solving the same issue in an overly client-friendly way, I think.

They can minimize the amount of code you write. Instead of spiking around like crazy, trying out stuff more freestyle, the practice of test-driving your code lets you write only the code that is necessary to pass your tests. No excess code. A thing you will often hear in your future career is that the best code is code you don’t have to write or something. Why? Well, most often, more elegant solutions involve lesser amounts of code and also, code that you don’t write—which might be unnecessary—won’t cause any future bugs and doesn’t need to be maintained. So writing the tests first, before you write the implementation, gives you a clear focus on which problem you need to solve next. Writing only code that is necessary, and not accidentally more, is maybe an underestimated side effect that TDD can provide you with. 

They have a positive effect on your design. To me, understanding this part turned on a light bulb and made me really appreciate the whole testing thing. When you write your implementations around very focused test scenarios, your code will most likely turn out to be much more compartmentalized and modular. Since we are all friends of DRY—“Don’t repeat yourself!”—and as little coupling between components in your app as possible, this is a simple but effective discipline to achieve systems which are designed well from the ground up. This aspect is the most important benefit, I think. Yes, the other ones are pretty awesome as well, but when tests also result in apps whose quality is better due to a refined design, I’d say Jackpot! 

It boils down to money as well. When you have a stable app that is easy to maintain and easy to change, you will save quite a bit of money in the long run. Unnecessary complexity can haunt projects easily, and motivation won’t be on an all-time high when your team has to fight your code because it’s brittle and badly designed. Good application design can absolutely support your business goals—and vice versa. Do you want to introduce some new features that are critical to your business, but you are constantly fighting your architecture because it was built on sand? Of course not, and we all have seen lots of examples of businesses that quickly disappeared for that exact reason. Good testing habits can be an effective line of defense for such situations. 

Another goal that is important is in respect to the quality of your code itself. The software you write should be easy to understand for other developers—as much as possible, at least. Your tests can really help to convey the functionality and intent of your application—and not only to other members on a team but to your future self as well. If you don’t touch a certain section of your code for quite a while, it will really be handy to refresh your memory of how and why you wrote a piece of software with the documentation that a tool such as RSpec provides—and RSpec does this really well, exceptionally actually.

Since your code will always change, refactoring your code will and should always be part of developing your software. And since change is so baked into this process, you need to make sure that these changes don’t generate unexpected side effects in surprising places. The test suite gives you a pretty tight-knit security net to feel more comfortable and free to refactor with gusto. This aspect, next to the design benefits TDD can provide you with, is my favorite benefit a test suite can help you with. Modifying and extending your code is such an essential component of innovating on your already released “product” that you need a tool that gives you as much freedom as possible with that process. I’m not sure if people who are critical of writing an extensive test suite are much concerned about this aspect.

You will have a good chance of building new stuff faster in later stages because the feedback from the test suite will give you feedback about your failures, bugs, and limitations—much faster than a human can test, of course. Plus, it will give you the confidence of working with a security net that becomes even more valuable the longer you go. 

In your apps, especially if they have grown significantly, you want to be able to trust your software. 100% code coverage sounds a lot sweeter when you have a site that is a couple of years old and touched by hundreds of developers. Being able to trust the new code you introduce and building on top of that is one of the blisses of software development that money can’t buy later on.

Getting Started

Terminal

-T lets you skip Test Unit, the testing framework that comes with Rails.

Gemfile

Terminal

After that we need to run a generator that comes with RSpec:

Terminal

Output

What this does is set up the basic structure for your RSpec tests within Rails. As you can see from the output above, this generator initialized a spec directory with a few files that you will need later. The .rspec file is a configuration file that we won’t need to manipulate for now. I just wanted to let you know what you have in front of you. The other files are self-explanatory, but I wanted to mention their differences.

  • spec_helper.rb is for specs that don’t depend on Rails.
  • rails_helper.rb, on the other hand, is for specs that do depend on it.

What is not obvious is that one of these files needs to be required on top of your spec files (test files) in order to run your tests. Let’s have a quick look! When you generate a model via: 

Terminal

Output

Not only will Rails have created the associated _spec.rb files for you, your specs will also automatically have require 'rails_helper' by default on top of your spec files. That means you are ready to go, right away. 

spec/models/dummy_model_spec.rb

So with this setup, you can test your Rails app, your models for example, and RSpec will not get confused about model classes used in Rails. This is necessary to require whenever you need stuff like ActiveRecord, ApplicationController and so on. So this is your normal scenario and therefore should be your first logical choice as a beginner.

Requiring spec_helper.rb, on the other hand, will throw an error if you write tests that include business logic from your Rails app. In that scenario, RSpec would not know what you are talking about when you want to test some Rails model, for example. 

So long story super short, spec_helper does not load Rails—that’s it! Of course, you can go wild with configurations, but this is nothing I want you to be concerned about right now. Let’s focus on the basics, how to run tests and the syntax. That should suffice for starters. Let’s move on!

Running Tests

You are ready to run your tests. RSpec requires your test files to have a specific suffix like _spec to understand which files to run. If you use a generator, this is not a concern, but if you want to write test files on your own, this is how they need to end. So you will need to put a file like your_first_test_spec.rb in your spec directory. 

Using the generator for creating a dummy model already provided us with spec/models/dummy_model_spec.rb. Not bad! One thing left to do before the tests are ready: 

Terminal

These commands run your migration for the dummy model we generated above, and set up the test database with that model as well. Now we actually run the test:

Terminal

The rake command will run all your tests, the complete test suite. Usually you should use this command when you have finished some feature and want to exercise the whole test suite.

Output

Congratulations! You just ran your first RSpec test. Not that bad, was it? Of course, this was a dummy test for now—with dummy test code generated by Rails. The more focused version of running your tests—you have actually a lot more options than only that—is to run an individual file, for example. Like this:

Terminal

This will only run a single test file instead of the whole test suite. With larger applications that depend on a high amount of test files, this will become a real time saver. But in terms of saving time and test specificity, this is only scratching the surface, to be frank. I think we will cover more of how to shave off a significant amount of time while testing in the third article in this series. Let’s see how far we get!

The other way to exercise the whole test suite is by simply running rspec—with or without bundle exec, depending on your setup.

Terminal

One more thing I should mention before we move on, you can also run only a specific subset of tests. Say you only want to run all of your tests for your model code:

Terminal

Easy as that!

Basic Syntax

I recommend that we start with the bare basics and look into a few more options that RSpec provides in the next two articles. Let’s have a look at the basic structure of a test and dive into more advanced waters when we've got this one out of the way.

  • describe

This will be your bread and butter because it organizes your specs. You can reference strings or classes themselves:

Some Spec

describe sections are the basic building blocks to organize your tests into logical, coherent groups to test. Basically, a scope for different parts of your application that you want to test.

Some Spec

A good tip is to tighten your scope even more. Since some classes will grow quite significantly, it’s not a good idea to have all the methods you want to test for one class in a single describe block. You can create multiple of these blocks, of course, and focus them around instance or class methods instead. To make your intent clearer, all you need is to provide the class name with an extra string that references the method you want to test.

Some Spec

That way you get the best of both worlds. You encapsulate related tests in their representative groups while keeping things focused and at a decent size. For users very new to Ruby land, I should mention that # simply references an instance method while the dot . is reserved for class methods. Because they are inside strings, they have no technical implications here, but they signal your intent to other developers and your future self. Don’t forget the comma after the class name—it won’t work without it! In a minute, when we get to expect, I’ll show you why this approach is super convenient.

  • it

Within the scope of describe groups, we use another scope of it blocks. These are made for the actual examples under test. If you want to test the instance method #favorite_gadget on the Agent class, it would look like this:

Some Spec

The string that you provide to the it block works as the main documentation for your test. Within it, you specify exactly what kind of behavior you want or expect from the method in question. My recommendation is not to go overboard and be too verbose about it but at the same time not to be overly cryptic and confuse others with overly smart descriptions. 

Think about what the smallest and simplest implementation of this part of the puzzle can and should accomplish. The better you write this part, the better the overall documentation for your app will be. Don’t rush this part because it’s just a string that can’t do any damage—at least not on the surface.

  • expect()

Now we’re getting more to the heart of things. This method lets you verify or falsify the part of the system you want to test. Let’s go back to our previous example and see it in (limited) action:

Some Spec

expect() is the “new” assertion syntax of RSpec. Previously we used should instead. Different story, but I wanted to mention it in case you run into it. expect() expects that you provide it with an object and exercise whatever method under test on it. Finally, you write the asserted outcome on the right side. 

You have the option to go the positive or negative route with .to eq or .not_to eq for example (eq being short for equal of course). You can always turn the logic around—whatever suits best your needs. Let’s run this nonsensical test and focus on the output that we got as a result of our test setup:

Terminal

Output

Reads pretty nice, doesn’t it? **"Agent#favorite_gadget returns one item, and the favorite gadget of the agent"** tells you all you need to know:

  • the class involved
  • the method under test
  • the expected outcome

If we had left off the string that describes the method in the describe block, then the output would have been a lot less clear and readable:

Some Spec

Output

Sure, there are other ways to circumvent and deal with this—passing this info via your it block, for example—but the other approach is just simple and works. Whatever makes your blood flow, of course!

Four Phases of a Test

Best practices in testing recommend that we compose our tests in four distinct phases:

  • test setup
  • test exercise
  • test verification
  • test teardown

These four phases are mostly for readability and to give your tests a conventional structure. It’s a so-called testing pattern, basically, a practice that the community widely agreed upon to be useful and recommended. This whole patterns topic is a deep rabbit hole, so know that I’ll leave out a bunch so as not to confuse the beginners among you to death. 

Setup

During setup, you prepare the scenario under which the test is supposed to run. In most cases, this will include data needed to be ready for some kind of exercise. Little tip: don’t overcomplicate things, and set up only the minimum amount necessary to make the test work.

Exercise

This part actually runs the thing that you want to test in this spec. Could be as simple as:

Verify

Now you verify if your assertion about the test is being met or not. So you test the system against your own expectations.

Teardown

The framework takes care of memory and database cleaning issues—a reset, basically. There's nothing for you to handle at this point. The goal is to get back a pristine state to run new tests without any surprises from the currently running ones. Let’s see what this would mean in a dummy example:

Some Spec

As you can see, in this example we separated the exercise and verify phases clearly from each other, whilst in the other dummy examples above, expect(agent.favorite_gadget).to eq 'Walther PKK, we mixed both phases together. Both are valid scenarios and have their place. Also, the new lines help to visually separate how the test is structured.

The Hard Thing About Testing

Now comes the hard part, what to test and how. In my opinion, this is the aspect of testing that is most confusing to newcomers—and understandably so! You are new to the language and framework and often don’t even know yet what you don’t know. How do you write tests for that? Very good question. 

I’ll be very frank, you don’t—most likely—and you won’t for quite a while. Getting comfortable with this stuff takes a while. When you have a mentor or attend some boot camp and such, you have the opportunity to directly learn from experienced people. In that case, your progress in this department will be different, of course.

On the other hand, if—like so many others out there—you are teaching yourself this stuff, patience will be key. Reading all the books and articles certainly gets you in the right direction, but I think that testing needs a lot of more advanced puzzle pieces in place in order for you to make complete sense and, maybe even more important, before you feel comfortable with it. 

The “good” news is that this is not unusual and we all have been there. Perseverance is important. You can do this, it’s no rocket science, but it will take a while until you can write an application effectively from the other way around—from the perspective of tests, I mean. For now, keep pushing, have fun, make mistakes, write apps, copy tutorials and whatnot, until the light bulb goes off.

Final Thoughts

When you write your individual tests, you want to make their objects do the simplest thing possible to achieve your goal—highly focused tests are really key. You want to design your application via very simple steps and then follow the errors your test suite is providing you with. 

Only implement what is necessary to get the app green. Not more, not less! That’s the “driven” part in test-driven development. Your work is guided by the needs of your tests.


RSpec Testing for Beginners, Part 2

RSpec Testing for Beginners, Part 2

The second article in this short series teaches you how to use various matchers that come with RSpec. It also shows you how to slice your test suite through tagging, how callbacks work, and how to extract some data. We expand a little on the basic survival kit from the first article and show you enough to be dangerous without too much rope to hang yourself.

Topics

  • Matchers
  • Let
  • Subjects
  • Callbacks
  • Generators
  • Tags

In the first article we spent quite a lot of time trying to answer the “why?” of testing. I suggest we get right back to the “how?” and spare ourselves any more context. We covered that part extensively already. Let’s see what else RSpec has to offer that you as a beginner can handle right away.

Matchers

So this is going to approach the heart of things. RSpec provides you with a ton of so-called matchers. These are your bread and butter when you write your expectations. So far you have seen .to eq and .not_to eq. But there is a much bigger arsenal to write your specs. You can test to raise errors, for truthy and falsy values, or even for specific classes. Let’s run down a few options to get you started:

  • .to eq
  • .not_to eq 

This tests for equivalence.

Some Spec

Attention!

To keep things short, I packed two expect statements within one it block. It is good practice, though, to test only a single thing per test. This keeps things a lot more focused, and your tests will end up less brittle when you change things.

  • .to be_truthy
  • .to be true

Some Spec

The difference is that be_truthy is true when it’s not nil or false. So it will pass if the result is neither of these two—kind of “true-like”. .to be true on the other hand only accepts a value that is true and nothing else.

  • .to be_falsy
  • .to be false

Some Spec

Similar to the two examples above, .to be_falsy expects either a false or a nil value, and .to be false will only do a direct comparison on false.

  • .to be_nil
  • .to_not be_nil

And last but not least, this tests exactly for nil itself. I spare you the example.

  • .to match()

I hope you already had the pleasure of looking into regular expressions. If not, this is a sequence of characters with which you can define a pattern that you put between two forward slashes to search strings. A regex can be very handy if you want to look for broader patterns that you could generalize in such an expression.

Some Spec

Suppose we're dealing with agents like James Bond, 007, who are assigned three-digit numbers. Then we could test for it this way—primitively here, of course.

  • >
  • <
  • <=
  • >=

Comparisons come in handy more often than one might think. I assume the examples below will cover what you need to know.

Some Spec

Now, we are getting somewhere less boring. You can also test for classes and types:

  • .to be_an_instance_of
  • .to be_a
  • .to be_an

Some Spec

In the dummy example above, you can see that a list of agents that are associated with a mission are not of class Agent but of ActiveRecord::Associations::CollectionProxy. What you should take away from this one is that we can easily test for classes themselves while staying highly expressive. .to be_a and .to be_an do one and the same thing. You have both options available to keep things readable.

Testing for errors is also massively convenient in RSpec. If you are super fresh to Rails and not sure yet which errors the framework can throw at you, you might not feel the need to use these—of course, that makes total sense. At a later stage in your development, you will find them very handy, though. You have four ways to deal with them:

  • .to raise_error

This is the most generic way. Whatever error is raised will be cast in your net.

  • .to raise_error(ErrorClass)

That way you can specify exactly which class the error should come from.

  • .to raise_error(ErrorClass, "Some error message")

This is even more fine grained since you not only mention the class of the error but a specific message that should be thrown with the error.

  • .to raise_error("Some error message)

Or you just mention the error message itself without the error class. The expect part needs to be written a little bit differently, though—we need to wrap the part under text in a code block itself:

Some Spec

  • .to start_with
  • .to end_with

Since we often deal with collections when building web apps, it’s nice to have a tool to peek into them. Here we added two agents, Q and James Bond, and just wanted to know who comes first and last in the collection of agents for a particular mission—here Moonraker.

Some Agent Spec

  • .to include

This one is also helpful to check the contents of collections.

Some Agent Spec

  • predicate matchers

These predicate matchers are a feature of RSpec to dynamically create matchers for you. If you have predicate methods in your models, for example (ending with a question mark), then RSpec knows that it should build matchers for you that you can use in your tests. In the example below, we want to test if an agent is James Bond:

Agent Model

Now, we can use this in our specs like so:

Some Agent Spec

RSpec lets us use the method name without the question mark—to form a better syntax, I suppose. Cool, ain’t it?

Let

let and let! might look like variables at first, but they are actually helper methods. The first one is lazily evaluated, which means that it is only run and evaluated when a spec actually uses it, and the other let with the bang(!) is run regardless of being used by a spec or not. Both versions are memoized, and their values will be cached within the same example scope.

Some Spec File

The bang version that is not lazily evaluated can be time-consuming and therefore costly if it becomes your fancy new friend. Why? Because it will set up this data for each test in question, no matter what, and might eventually end up being one of these nasty things that slow down your test suite significantly.

You should know this feature of RSpec since let is widely known and used. That being said, the next article will show you some issues with it that you should be aware of. Use these helper methods with caution, or at least in small doses for now.

Subjects

RSpec offers you the ability to declare the subject under test very explicitly. There are better solutions for this, and we will discuss the downsides of this approach in the next article when I show a few things you generally want to avoid. But for now, let’s have a look at what subject can do for you:

Some Spec File

This approach can, on the one hand, help you with reducing code duplication, having a protagonist declared once in a certain scope, but it can also lead to something called a mystery guest. This simply means that we might end up in a situation where we use data for one of our test scenarios but have no idea anymore where it actually comes from and what it is comprised of. More on that in the next article.

Callbacks

In case you are not aware of callbacks yet, let me give you a brief heads up. Callbacks are run at certain specific points in the lifecycle of code. In terms of Rails, this would mean that you have code that is being run before objects are created, updated, destroyed, etc. 

In the context of RSpec, it’s the lifecycle of tests being run. That simply means that you can specify hooks that should be run before or after each test is being run in the spec file, for example—or simply around each test. There are a few more fine-grained options available, but I recommend we avoid getting lost in the details for now. First things first:

  • before(:each)

This callback is run before each test example.

Some Spec File

Let’s say you would need a certain gadget for every test you run in a certain scope. before lets you extract this into a block and prepares this little snippet for you conveniently. When you set up data that way, you have to use instance variables, of course, to have access to it among various scopes.

Attention!

Don’t get fooled by convenience in this example. Just because you can do this kind of stuff does not mean you should. I want to avoid going into AntiPattern territory and confuse the hell out of you, but on the other hand, I want to explain the downsides to these simple dummy exercises a bit as well. 

In the example above, it would be much more expressive if you set up the needed objects on a test-by-test basis. Especially on larger spec files, you can quickly lose sight of these little connections and make it harder for others to piece together these puzzles.

  • before(:all)

This before block runs only once before all the other examples in a spec file.

Some Spec File

When you remember the four phases of test, before blocks sometimes are helpful in setting something up for you that needs to be repeated on a regular basis—probably stuff that is a bit more meta in nature.

after(:each) and after(:all) have the same behavior but are simply run after your tests have been executed. after is often used for cleaning up your files, for example. But I think it’s a bit early to address that. So commit it to memory, know that it’s there in case you start needing it, and let’s move on to explore other, more basic things.

All of these callbacks can be placed strategically to fit your needs. Place them in any describe block scope that you need to run them—they don’t have to necessarily be placed on top of your spec file. They can easily be nested way inside your specs. 

Some Spec File

 As you can observe, you can place callback blocks at any scope to your liking, and go as deep as you need. The code in the callback will be executed within the scope of any describe block scope. But a little bit of advice: if you feel the need of nesting too much and things seem to get a little bit messy and complicated, rethink your approach and consider how you could simplify the tests and their setup. KISS! Keep it simple, stupid. Also, pay attention to how nicely this reads when we force these tests to fail:

Output

Generators

Let’s also have a quick look at what generators are provided by RSpec for you. You have already seen one when we used rails generate rspec:install. This little fella made setting up RSpec for us quick and easy. What else do we have?

  • rspec:model

Want to have another dummy model spec?

Terminal

Output

Quick, isn’t it? Or a new spec for a controller test, for example:

  • rspec:controller

Terminal

Output

  • rspec:view

The same works for views, of course. We won’t be testing any views like that, though. Specs for views give you the least bang for the buck, and it is totally sufficient in probably almost any scenario to indirectly test your views via feature tests. 

Feature tests are not a specialty of RSpec per se and are more suited to another article. That being said, if you are curious, check out Capybara, which is an excellent tool for that kind of thing. It lets you test whole flows that exercise multiple parts of your app coming together—testing complete features while simulating the browser experience. For example, a user who pays for multiple items in a shopping cart.

  • rspec:helper

The same generator strategy lets us also place a helper without much fuss.

Terminal

Output

The double helper_helper part was not an accident. When we give it a more “meaningful” name, you will see that RSpec just attaches _helper on its own.

Terminal

Output

A Word About Helpers

No, this directory is not a place to hoard your precious helper methods that come up while refactoring your tests. These would go under spec/support, actually. spec/helpers is for the tests that you should write for your view helpers—a helper like set_date would be a common example. Yes, complete test coverage of your code should also include these helper methods. Just because they often seem small and trivial doesn’t mean that we should overlook them or ignore their potential for bugs we want to catch. The more complex the helper actually turns out, the more reason you should have to write a helper_spec for it!

Just in case you start playing around with it right away, keep in mind that you need to run your helper methods on a helper object when you write your helper tests in order to work. So they can only be exposed using this object. Something like this:

Some Helper Spec

You can use the same kind of generators for feature specs, integration specs and mailer specs. These are out of our scope for today, but you can commit them to memory for future use:

  • rspec:mailer
  • rspec:feature
  • rspec:integration

A Look at Generated Specs

The specs we created via the generator above are ready to go, and you can add your tests in there right away. Let’s have a tiny look at a difference between specs, though:

spec/models/dummy_model_spec.rb

spec/controllers/dummy_controller_controller_spec.rb

spec/helpers/dummy_helper_helper_spec.rb

It doesn’t need a wunderkind to figure out that they all have different types. This :type RSpec metadata gives you an opportunity to slice and dice your tests across file structures. You can target these tests a bit better that way. Say you want to have some sort of helpers only loaded for controller specs, for example. Another example would be that you want to use another directory structure for specs that RSpec does not expect. Having this metadata in your tests makes it possible to continue to use RSpec support functions and not trip up the test suite. So you are free to use whatever directory structure works for you if you add this :type metadata.

Your standard RSpec tests do not depend on that metadata, on the other hand. When you use these generators, they will be added for free, but you can totally avoid them as well if you don’t need them. 

You can also use this metadata for filtering in your specs. Say you have a before block that should run only on model specs, for example. Neat! For bigger test suites, this might come in very handy one day. You can filter which focused group of tests you want to run—instead of executing the whole suite, which might take a while. 

Your options extend beyond the three tagging options above, of course. Let’s learn more about slicing and dicing your tests in the next section.

Tags

When you amass a bigger test suite over time, it won’t just be enough to run tests in certain folders to run RSpec tests quickly and efficiently. What you want to be able to do is run tests that belong together but might be spread across multiple directories. Tagging to the rescue! Don’t get me wrong, organizing your tests smartly in your folders is key as well, but tagging takes this just a bit further.

You are giving your tests some metadata as symbols like “:wip”, “:checkout”, or whatever fits your needs.  When you run these focused groups of tests, you simply specify that RSpec should ignore running other tests this time by providing a flag with the name of the tags.

Some Spec File

Terminal

Output

You could also run all kinds of tests and ignore a bunch of groups that are tagged a certain way. You just provide a tilde (~) in front of the tag name, and RSpec is happy to ignore these tests.

Terminal

Running multiple tags synchronously is not a problem either:

Terminal

As you can see above, you can mix and match them at will. The syntax is not perfect—repeating --tag is maybe not ideal—but hey, it’s no biggie either! Yes, all of this is a bit more extra work and mental overhead when you compose the specs, but on the flip side, it really provides you with a powerful ability to slice up your test suite on demand. On bigger projects, it can save you a ton of time that way.

Final Thoughts

What you've learned so far should equip you with the absolute basics to play with tests on your own—a survival kit for beginners. And really do play and make mistakes as much as you can. Take RSpec and the whole test-driven thingie for a spin, and don’t expect to write quality tests right away. There are still a couple of pieces missing before you will feel comfortable and before you will be effective with it. 

For me, this was a bit frustrating in the beginning because it was hard to see how to test something when I hadn’t yet implemented it and didn’t fully understand how it would behave. 

Testing really proves whether you understand a framework like Rails and know how the pieces fit together. When you write tests, you will need to be able to write expectations for how a framework should behave. 

That is not easy if you're just starting out with all of this. Dealing with multiple domain-specific languages—here RSpec and Rails, for example—plus learning the Ruby API can be confusing as hell. Don’t feel bad if the learning curve seems daunting; it will get easier if you stick with it. Making this light bulb go off won’t happen over night, but to me, it was very much worth the effort.