Tag: command line

Seeing And Saying On The Command Line

Occasionally I like command line tools to also say the output, in addition to ‘printing’ it (to STDOUT).

A current context is starting a server locally with updated information. The start up takes time, so I tend to not wait at the command line for it to fully boot.

I wanted a noticeable signal when the thing is up – and also a confirmation that the version of the information source *is* actually updated. The commands tee and (the macOS) say do this for me:

tee >(say&)

tee copies the output of its input to STDOUT (usually the terminal) and the given file. The construction >(other command&) causes tee to send the input not to a file but to othercommand and the & causes that command to return immediately (instead of returning only after the command to finish).

Overall, I do something like this. The system returns a lengthy JSON string, so I use jq to get to the version information I’m looking for:

curl -s -u <username:thepassword> “<url_to_locally_running_service>” | jq “<path_to_version_info_in_json>” | tee >(say&)

The GitHub page explains that

jq is a lightweight and flexible command-line JSON processor.

https://stedolan.github.io/jq/

It’s well worth trying, if you’re dealing with JSON input on the command line.

Tools for Testing — 2

Just like the first tool for testing ‘GraphViz’ I briefly described earlier, today’s tool is not limited to be used in testing.

In most of my projects, I use the command line a lot. My colleague Marcus Franke pointed me to autojump, which allows you to quickly navigate directory structures, as well as open folders in a GUI tool like the Finder (or Pathfinder) on a Mac (and I’m sure it works similarly on Windows & Linux).

As the project page says:

autojump is a faster way to navigate your filesystem. It works by maintaining a database of the directories you use the most from the command line.

I use a Mac (most of the time) as well as Homebrew, so the installation of autojump was simple:

brew install autojump

After using cd to navigate to my most visited directories to ‘train’ auto jump, I can use ‘j d’ to jump into my dev folder, which is where I keep all my project directories:

$ j d
/Users/stephan/dev
~/dev $

Yes, it’s just three key strokes: ‘j’, space and ‘d’. I like this quick way to jump between directories, because it’s a lot less typing (compared to entering the real path names) and moving back and forth in the directory structure is pretty easy and fast.

A Surprising Use of an Interface

This post relates to my short talk at the Agile Testing Days in Potsdam, Germany 2012.

Earlier this year I tweeted this (there’s another blog post about this as well):

Automating tests/checks, seems more valuable than having automated tests—like planning being more valuable than having the plan.

In my case the automating certainly led to other interesting results — and that’s the topic of this post.

Some context

Let’s assume we’re using Cucumber to automate tests for some application and follow the typical Cucumber setup: A folder features containing the feature files and inside of that another folder (step_definitions) containing, well, the step definitions. A support folder inside the feature directory keeps supporting files, such as environment configuration(s) etc.

Keeping it clean

The way I started to work is to start simple: At first I put everything inside the step definitions. Pretty soon though, I extract code chunks into methods of their own. And then move those method definitions into their own class (or module) – an in fact a file of their own.

That way, I end up with two more levels of abstraction below the feature descriptions and the step definitions: Classes (or modules) containing method definitions (see picture).

feature files, step defs, classes/modules, methods

Here I follow Uncle Bob Martin‘s advice of “Extract till you drop” (see his book ‘Clean Code‘, and episode 3 (Functions) of the video series at cleancoders.com): Extract methods until there’s nothing left to extract (and extract that code into the right place).

A first result: A high level interface to the system

One of the results of doing this, is a really high level and clean API to the system at hand. In addition to that I find that step definitions are much easier to understand, since they (mostly) contain a business level description of how the system is used and accompanying assertions to check whether the system behaves as it should.

Enter Pry

Pry is a command line tool for Ruby, like the interactive ruby shell irb that comes with Ruby. However, Pry is a lot more powerful and offers to display method definitions (even those defined in the C sources of internal Ruby classes) and a whole lot more. For a good introduction see the Pry Screencast by Josh Cheek on vimeo.

A trivial and contrived example

Let’s assume we’re trying to find stuff on the web (I’m on a Mac; there are hints about how to achieve this on Windows in the code comments):

require 'safariwatir' # Windows: require 'watir'

class GoogleSearch
 def initialize
 @browser = Watir::Safari.new # Win: Watir::Browser.new
 end

 def search_for search_term
 @browser.goto 'http://wellknown-search-engine.example.com/'
 @browser.text_field( :name, 'q' ).set search_term
 @browser.button( :id, 'gbqfb' ).click
 @browser.ol( :id, 'rso' ).links.map(&amp;amp;amp;:text)
 end
end

Given that interface and Ppy, the creation of a console app borders on being trivial (yet, it took me a long while to get to this point):

require_relative 'google_search'
require 'pry'

GoogleSearch.new.pry

Think about this for a moment: Take Pry and your API and in 3 lines of code you get a console app for your system. The console can be used like this:

[10] stephan@nibur … #ruby google_search_console.rb
[1] pry(#&lt;GoogleSearch&gt;):1&gt; search_for 'pry video josh'
=&gt; ['Pry Screencast on Vimeo',
# ...

As mentioned above, you can even display the method definition (including lines of code, file name etc.)

[8] pry(&lt;GoogleSearch&gt;)&gt; show-method search_for

From: /Users/stephan/…/google_search.rb @ line 8:
Number of lines: 6
Owner: GoogleSearch
Visibility: public

def search_for search_term
 @browser.goto 'http://google.de/'
 @browser.text_field( :name, 'q' ).set search_term
 @browser.button( :id, 'gbqfb' ).click
 @browser.ol( :id, 'rso' ).links.map(&amp;amp;amp;:text)
end
[9] pry(#&amp;amp;lt;GoogleSearch&amp;amp;gt;)&amp;amp;gt;…

Leaving thoughts

It seems that doing something can be more valuable that having the result. Notwithstanding, we still need to produce something of value for our business.

I came to realise that clean code matters more than ‘only’ providing a code base that’s easy to understand and change: Without the high level API, I might not even have noticed the possibility to create a ‘business level console’.

Having a console app like this allows to prepare starting points for exploratory testing (that might be ‘automation assisted exploring). Or short: I think a clean and high-level interface plus Pry is a cool tool for exploration.

Navigation

%d bloggers like this: