Tag Archives: Testing

Hello, is Elixir there?

So, another day, another … well, sorry, I just can’t find something funnier to start with! Anyway, this time it’s the “hey, let’s format some phone numbers, but let’s do it for US only” kind of problem.

And today, the highlights are:

Tuples & pattern matching

Let’s say that you have a function that knows how to split a phone number into meaningful parts (hmm, I wonder where did I get that idea?!). So you might end up with code area of that phone number, prefix and finally line number.

The question is, how do you pass that information around? Well, aside from structs, you can just use tuples. Just wrap values in curly braces and that’s it:

defp split(phone) do
  {code(phone), prefix(phone), line(phone)}
end

This effectively means that the output might be something like {“123”, “456”, “7890”}. The good thing about that, as opposed to using for example a list, is that you can easily access each member, by index, or just use pattern matching to extract values, like this:

def pretty(phone) do
  {code, prefix, line} = split(phone)
  "(#{code}) #{prefix}-#{line}"
end

That way, it’s pretty easy to pass multiple results around.

Guard clauses

Until now, I didn’t really have a use for those. But, this time, the sort of complex number format and validation rules complicate things, and guard clauses help with the reasoning.

def number(raw) do
  case raw |> String.replace(~r/\W/, "") |> to_char_list do
    phone when length(phone) == 11 and hd(phone) == ?1 ->
      tl(phone)
    phone when length(phone) != 10 ->
      '0000000000'
    phone ->
      phone
  end |> to_string
end

This way, the rules become easy to follow. And situations like “if phone length is 11 and starts with ‘1’, then it’s a valid number but remove the ‘1’ before moving on” become easy to write and follow quite nicely the natural language.

Doctest

Doctest is a great thing all modern languages support. The idea is to write examples as part of a function documentation, and have test execute those very examples. So, the phrase “the tests are the code’s documentation” comes to life in a splendid manner 🙂

This specific exercism.io problem had some of those already in the supplied exercise code, and I wanted to use those tests as well. If we were to use `mix`, then it would be easy, since the tool would set up everything for us. But, since exercism.io problems are meant to offer as little distraction as possible, you can’t use it out of the box.

Fortunately, there is a work around. You just need to:

  • add `doctest Phone` to the test file / module, as shown here
  • build source file, because otherwise doctest will not find the documentation
  • run tests as usual

So, for the last 2 steps, just create a shell script that does that for you. For example:

elixirc phone_number.exs && elixir phone_number_test.exs

Elixirc compiles the code, creating a beam file, tests load it and use it to run the tests / examples from documentation. And oh, forgot to show an example of such a test:

  @doc """
  Remove formatting from a phone number.

  ## Examples
  iex> Phone.number("123-456-7890")
  "1234567890"
  """
  def number(raw) do
  end

And, when executed, it reports like this:

$ ./test.sh
PhoneTest
  * doc at Phone.number/1 (4) (0.7ms)

Finished in 0.1 seconds (0.1s on load, 0.01s on tests)
1 tests, 0 failures

Randomized with seed 543612

That’s it folks!

Here’s a Github issue that related to all of this.

You can find the entire phone number solution here.

P.S. All pun intended 🙂

Tagged , , ,

Karma & Browserify

Recently I had the pleasure of setting up Angular tests within a project. For testing, we decided on Karma test runner by Angular team. You can find details about the reasoning at the end of the post, but basically the idea was that we’d like to stick with the runner built and used by the Angular team itself.

The project is currently a Rails gem and there are a bunch of nice tutorials on how integrate the two (see resources), but this project has aspirations to become a full-blown Angular app without any direct Rails dependencies. So, solutions like rails_karma gem or rails assets was not an option. 

The good news is that the project in question used Browserify and sprockets-browserify gem to integrate it into Rails. After a bit of investigation, we came upon karma-browserify node module. This way, the resources under test were still served by browserify in the same manner as they would be served with the live application, but Rails was actually not needed to run the tests. The module in question essentially adds Karma preprocessors that make Karma aware of browserify served resources. In the end, this made our tests run fast, without involving Rails, which is a nice bonus.

The coffeescript configuration that ended up running the test suite:


module.exports = (config) ->
 config.set
 basePath: '..'

frameworks: [
 'jasmine'
 'browserify'
 ]

preprocessors:
 'app/assets/javascripts/index.coffee': ['browserify'] # index contains all requires
 'spec/**/*.coffee': ['coffee']

browserify:
 extensions: ['.coffee']
 transform: ['coffeeify']
 watch: true
 debug: true

 files: [
 'spec/support/karma_init.coffee'
 'app/assets/javascripts/index.coffee' # load the application, have browserify serve it
 {
 # watch application files, but do not serve them from Karma since they are served by browserify
 pattern: 'app/assets/javascripts/*.+(coffee|js)'
 watched: true
 included: false
 served: false
 }
 'spec/support/**/*.+(coffee|js)' # load specs dependencies
 'spec/javascripts/**/*_spec.+(coffee|js)' # load the specs
 ]

exclude: []
 reporters: ['progress']
 port: 9876
 colors: true
 logLevel: config.LOG_INFO
 autoWatch: true
 browsers: ['PhantomJS']
 captureTimeout: 60000
 singleRun: false

Just run karma with karma start spec/karma.config.coffee and that’s it.

Resources:

Tagged , , , , ,

Java RSpec alternative

I simply adore RSpec in Ruby land 🙂 It helped me embrace TDD in the best manner possible – by not getting into my way. Doesn’t sound much but it feels great when TDD cycle is so fast and unobtrusive that one simple cannot help running the spec over and over again. I don’t know, for me it feels like “let’s run the specs once again, if nothing else than to see how fast they run”. Compulsive but I can’t help it 🙂

Anyway, I’ve been working on some Java projects these couple of weeks and wanted the same TDD comfort zone as I get with RSpec. And a combination of Mockito, JUnit and PowerMock seems to be doing the trick. How about some code?:

public final class Blender {
  // ...
}

public class CreateYummyShake {
  private Blender blender;

  public CreateYummyShake(Blender blender) {
    // ...
    this.blender = blender;
  }

  public Shake with(List fruit) {
    return mix(takeRipe(fruit));
  }

  private Shake mix(List fruit) {
    // mix the fruit using blender
    // put it in glass
    // ...
  }

  protected List takeRipe(List Fruit) {
    new FilterFruit(fruit).takeRipe();
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Blender.class})
public class CreateYummyShakeTest {
  private Blender blender;

  @Before
  public void setup() {
    fruit = new ArrayList();
    fruit.add(mock(Fruit.class));
    fruit.add(mock(Fruit.class));
    blender = PowerMockito.mock(Blender.class); // mock final class with PowerMockito
    subject = spy(new CreateYummyShake(blender)); // spy the subject of the test, we need this later
  }

  @Test
  public void createsYummyShake() {
    doReturn(ripeFruit).when(subject).takeRipe(anyCollectionOf(Fruit.class)); // intercept call to another use case, no need to test this since it has it's own test
    when(blender.blend(fruit)).thenReturn(...); // use PowerMockito mock as you would use a Mockito one
    assertArrayEquals(ripeFruit.toArray(), subject.with(allFruit).ingredients.toArray());
  }
}

Before I explain this, a quick disclaimer: this code is nowhere near perfect or even nice, but hopefully it server the purpose of exposing some details about the test tools used. Consider yourself warned 🙂

Anyway, as you can see, Mockito plays well with collaborators and other use cases in the code. However, it can’t mock final classes (and some other combinations too, but you can look it up if need be). That’s where PowerMock comes in. It does the job, and as a bonus it lets you use those mock with Mockito as if nothing changed.

Also, subject under test might be using some other collaborator (ripe fruit filter in this case) and have a hard connection to it. Now, usually this would be injectable and easily mocked in test, but for the sake of argument, how does one test this? By extracting access to that collaborator to a protected method and stubbing it’s result. Mockito offers the ability to spy the subject under test. This way, the extracted access method can be mocked and the test is simplified. A separate test for the collaborator should exist of course.

The rest of Mockito DSL and options is pretty nice. It it not as pleasant as RSpec but it comes pretty close. I’ve always liked how RSpec tests read like prose, and this comes pretty close. The only issue I have is with asserts, but that can’t be helped unless JRuby is used, but that’s another story altogether.

Lastly, if you use Maven, you need these dependencies:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.10</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-all</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>1.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito</artifactId>
  <version>1.5</version>
  <scope>test</scope>
</dependency>
Tagged , , , ,