I have no idea how many times I’ve typed code like this (to do printf-style debugging):
my_hash.each_pair do |key, value|
p [key, value]
I’ve finally wised up, and built a helper method to support this:
The method allows any data, and specifically supports Hash-like and Array-like structures.
It also allows an optional name (defaults to data class-name) and message.
a => 0
b => 1
c => 2
And here’s my helper class:
# Class to help in 'printf' debugging.
def self.printf(data, name = data.class.to_s, description = '')
size = data.respond_to?(:size) ? data.size : 1
puts format('%s (size=%d) %s', name, size, description)
data.each_pair do |k, v|
puts format(' %s => %s', k, v)
# Array-like or Set-like.
data.each_with_index do |v, i|
puts format(' %6d: %s', i, v)
puts format(' %s', data.inspect)
“Test Automation Professional / Zealot” is the title I have in my resume.
But I’m not a tester, and still less a “quality” engineer.
Then what am I?
To borrow from mountain-climbing vocabulary, I’m not a climber, I’m a sherpa — one who does much of the heavy lifting, creates base camps, and keeps the climbers progressing happily and safely.
In that spirit, I aim to make it possible for others to do automated testing easily and reliably.
For a year now I’ve worked on my GitHub project, RubyTest, which embodies what I’ve learned in long years of building test automation.
- Core (application-independent) support:
- Base classes
- Helper classes
- Unit testing for the core (of course!).
- Example domain-specific code:
- Page objects, for web UI testing.
- Endpoint objects, for TEST API testing.
- Data objects, for both types of testing.
- Example domain-specific tests.
Most recently, I’ve been building a Tester Tour of part of the project — the part that demonstrates testing for a REST API and a web UI. (The demo test targets are GitHub’s own REST API and web UI.)
You can see the tour here.
Any feedback appreciated, either as Issues on GH, comments here, or private email.
In my automated testing, I often want to test a pair of hashes for equality. If the pair is equal, well enough.
But if they’re not equal, the simple way to record that is to log the failure, along with the two hashes. If the hashes are very small: I can visually compare them to determine the differences.
But for larger hashes, I can’t easily determine the differences visually. That’s where my class
HashHelpler comes in.
It has method
HashHelper.compare(expected, actual) that accepts the expected and actual hashes, and returns a hash having four keys and their corresponding values:
:ok: value is a hash containing the key/value pairs that are in both
:missing: value is a hash containing the key/value pairs that are in
expected, but not in
:unexpected: value is a hash containing the key/value pairs that are in
actual, but not in
:changed: value is a hash detailing the keys that are in both
actual, but whose values differ.
So: in my method
Log#verdict_assert_equal?, a failed hash comparison gets and logs the detailed differences, making it easy to see what’s what.
Hey, Ruby coders!
Do you recognize this idiom?
Or this one?
When I wanted to do these two things in my RubyTest project, I had to Google to find out how.
Now if I put this code into my project, will I recognize these idioms later on? Next month? Next year?
I could add comments to explain, but a comment can get stale (not keep up with code changes), or get separated from its code, or even get deleted.
You can help your downstream code enhancer/maintainer by pushing an unusual idiom into a well-named method.
(Hint: If you’re not sure who is the downstream enhancer/maintainer, it’s you!)
Thus, I created this:
def self.instantiate_class_for_class_name(class_name, *args)
PS: My GitHub project is about test automation in Ruby. It has a Tester Tour of the demo testing for a web UI and for a REST API.
Over at my GitHub project, RubyTest, I’ve added an example Changes Report.
This is the report that I rely on the most.
Check it out.