A Cucumber Kimchi Recipe

My wife and I love to eat kimchi. Recently, I started making it at home instead of buying the big (expensive) jars at our local Asian market. I just made oi-sobagi (오이소박이), a cucumber kimchi, for the first time. Given that “Cucumber” is a test automation buzzword, I figured I’d share the recipe here. I hope you enjoy it as much as my Chinese cucumber recipe!

The recipe I used came from Maangchi, “YouTube’s Korean Julia Child.” She has many other delicious Korean recipes, too. Her oi-sobagi recipe is here:

Clicking Web Elements with Selenium WebDriver

Selenium WebDriver is the most popular open source package for Web UI test automation. It allows tests to interact directly with a web page in a live browser. However, using Selenium WebDriver can be very frustrating because basic interactions often lack robustness, causing intermittent errors for tests.

The Basics

One such vulnerable interaction is clicking elements on a page. Clicking is probably the most common interaction for tests. In C#, a basic click would look like this:

webDriver.FindElement(By.Id("my-id")).Click();

This is the easy and standard way to click elements using Selenium WebDriver. However, it will work only if the targeted element exists and is visible on the page. Otherwise, the WebDriver will throw exceptions. This is when programmers pull their hair out.

Waiting for Existence

To avoid race conditions, interactions should not happen until the target element exists on the page. Even split-second loading times can break automation. The best practice is to use explicit waits before interactions with a reasonable timeout value, like this:

const int timeoutSeconds = 15;
var ts = new TimeSpan(0, 0, timeoutSeconds);
var wait = new WebDriverWait(webDriver, ts);

wait.Until((driver) => driver.FindElements(By.Id("my-id")).Count > 0);
webDriver.FindElement(By.Id("my-id")).Click();

Other Preconditions

Sometimes, Web elements won’t appear without first triggering something else. Even if the element exists on the page, the WebDriver cannot click it until it is made visible. Always look for the proper way to make that element available for clicking. Click on any parent panels or expanders first. Scroll if necessary. Make sure the state of the system should permit the element to be clickable.

If the element is scrolled out of view, move to the element before clicking it:

new Actions(webDriver)
    .MoveToElement(webDriver.FindElement(By.Id("my-id")))
    .Click()
    .Perform();

Last Ditch Efforts

Nevertheless, there are times when clickable elements just don’t cooperate. They just can’t seem to be made visible. When all else fails, drop directly into JavaScript:

((IJavaScriptExecutor)webDriver).ExecuteScript(
    "arguments[0].click();",
    webDriver.FindElement(By.Id("my-id")));

Do this only when absolutely necessary. It is a best practice to use Selenium WebDriver methods because they make automated interaction behave more like a real user than raw JavaScript calls. Make sure to give good reasons in code comments whenever doing this, too.

Final Advice

This article was written specifically for clicks, but its advice can be applied to other sorts of interactions, too. Just be smart about waits and preconditions.

Note: Code examples on this page are written in C#, but calls are similar for other languages supported by Selenium WebDriver.

A Panda’s Retrospective on The Legend of Zelda: Breath of the Wild

Warning #1: This post has nothing to do with software development or testing. It is purely a post for my own pleasure.

Warning #2: SPOILER ALERT! This post is full of ’em.

The Legend of Zelda: Breath of the Wild is one of my favorite video games. Ever. I’ve been playing it regularly on my Wii U since Christmas, and I just beat the main quest. I redeemed all four Divine Beasts, found all 120 shrines, recovered all memories, and got a majority of the Korok seeds and Hyrule Compendium. It was truly the (virtual) adventure of a lifetime! In celebration of finally beating the game, I’m going to retrospect on what I loved about it so much.

What’s It About?

If you don’t know what this game is about, watch this:

Here’s the story: You, as a young man named Link, wake up in a cave with no memory about yourself or your past. As you explore the world and recover your memories, you discover that the kingdom of Hyrule was destroyed 100 years ago by the evil Calamity Ganon. Princess Zelda has sealed Ganon inside Hyrule Castle since then, but her power is weakening. You, along with four other “champions,” fought together to defeat Ganon but failed, and you yourself were nearly killed. Your main mission is to explore the land to strengthening yourself, recover lost memories, and reawaken four divine beasts. Then, you need to storm the castle to defeat Ganon, rescue Zelda, and bring a lasting peace to Hyrule.

How I Played

When BOTW was first announced as an open-world adventure, I immediately shut out all news and reviews aside from official trailers. I adamantly did not want any spoilers whatsoever. I wanted to fully explore the game on my own. And, truth be told, it was totally worth it.

When I play video games, I tend to be a completionist. I like to leave no stone unturned, and I take time to power up as much as possible before big challenges. As a result, my progress rate in BOTW was rather slow, but I feel like I didn’t miss out on anything. Even then, there are still side quests left incomplete and Korok seeds left unfound. All told, I spent 241 hours on a single save file.

botw_playtime

My total playtime after defeating Ganon.

After completing the Great Plateau and fully restoring the Sheikah Slate, my main approach to exploration was to look for shrines in a new area using the binoculars, make a mad rush for the shrine to claim a safety post, and then thoroughly search the surrounding areas for new stuff. I literally went around blind because I didn’t know where to find the Divine Beasts. Here’s roughly the path I took:

  1. Scoured Necluda for shrines for a while.
  2. Went to Zora’s Domain and reclaimed Vah Ruta.
  3. Went to the Great Hyrule Forest but couldn’t take the Master Sword.
  4. Found the Ancient Tech Lab in Akkala.
  5. Criss-crossed Hyrule Field and got blown up by Guardians.
  6. Climbed Mount Lanayru and OH CRAP THERE’S A DRAGON!
  7. Cross-dressed my way through the Gerudo Desert and reclaimed Vah Nabooris.
  8. Froze my butt off in the Gerudo Highlands.
  9. Rode through Lake Hylia and Faron.
  10. Took wings in Tabantha and reclaimed Vah Medoh.
  11. Set my butt on fire on Death Mountain and reclaimed Vah Rudania.
  12. Decided to freeze my butt off again, but this time in Hebra.
  13. Stormed Hyrule Castle, kicking butt and taking names.

For combat, I really preferred nimble melee combat. I favored single-handed weapons and spears. I got pretty good with arrows, too, and I would often try to sneak around as an archer before wailing on enemies with a sword.

guardian_artwork

Guardians – ruining Link’s day, every day.

I did not purchase the DLC, and I probably won’t anytime soon. Why? I simply don’t have time. I didn’t feel like the game was lacking without the DLC, though it looks like it adds some cool content.

What I Loved

The open world was breathtaking. The scenery was truly beautiful, and the whole game was completely explorable. Except for the very edges of the map, there were no invisible walls: if it was there, you could climb it or jump it.

https3a2f2fblueprint-api-production-s3-amazonaws-com2fuploads2fcard2fimage2f6711412fcfc041c6-cef4-4b89-8745-b3cf1d7a8570

It’s just wild.

As the player, you chose the order of events. In other Zelda games, as in most adventure games, the main quest is completely linear. The player must complete events in a certain order to progress. However, in BOTW, after fully restoring the Sheikah Slate, you can make up your own adventure. The divine beasts are recommended but not required. You can even attempt to fight Ganon immediately after stepping off the Great Plateau (though the King’s ghost rightfully says that would be foolish). If I were to play it again, I’d probably do this order: Necluda/Faron, Great Hyrule Forest, Zora’s Domain, Death Mountain, Tabantha, and Gerudo Desert.

The non-linear unfolding of memories made the story so much more engaging. Until you beat the main quest, you really don’t know everything that happened in the past. You find out bits and pieces about Link, Zelda, and the Champions all throughout the quest. The flashbacks become wonderful rewards for progression.

The Sheikah. My favorite race in BOTW are the Sheikah. They are bona fide ninjas with Jōmon stylistics. They’re the underdog good guys who help Link. They made the greatest technology in Hyrule. And for once, the Sheikah are a living, thriving people group. I loved running around Hyrule wearing the Sheikah armor in honor of the Sheikah.

tumblr_oq01gwfwmp1qhgj2mo1_500

I want a man bun like that.

The Gorons are hilarious. If the Sheikah are my #1, then the Gorons are my #2. They’re very friendly people with priceless facial expressions.

This slideshow requires JavaScript.

The music was elegantly serene. It always perfectly complemented the location. From the piano taps while crossing the fields on horseback, to the rambunctious trombones of Goron City, to the violins of Hateno Village that could move you to tears, the music was on point.

Sheikah technology is so cool. Link is running around Hyrule with a mobile phone. The only thing it can’t do is make phone calls!

sheikah-slate-breath-of-the-wild

So, somehow, Hyrule regressed after 10,000 years?

Cooking. I love cooking. The fact that it’s in a Zelda game is incredible. ‘Nuff said.

5c06dba4cd3432d490d919c0895ff0e4

Iron Chef Link!

Favorite Moments

Meeting the Sheikah monk at the end of every shrine. I loved how each monk had a unique name and pose. I also loved how the blue light would shatter as the monk blessed you with the Spirit Orb.

026

Every time was a special encounter.

The first horse. Taming, riding, and domesticating my first horse blew my mind. (Remember, I had no spoilers, not even horses.) I still have my first horse, a brown one with a white butt who I named Buttercup.

buttercup.jpg

Look at mah horse – mah horse is amazing!

The first Lynel defeat. I felt UNSTOPPABLE.

ee9

This is not easy.

The first blood moon. I panicked because I had no idea what was happening.

Discovering the Great Skeleton in Hebra. It’s in a secret, beautiful cavern under a mountain peak.

Defeating Master Kohga. I delighted in sending him straight down to hell where he belonged. I had zero tolerance for the Yiga Clan.

Finding Gorons in Gerudo Town. They don’t even know how they got it!

gtxdtk9zj7ny

It must be the gems.

Building Tarrey Town. Tarrey town is the place where all the races come together to build a productive new settlement together in peace. Everyone gets along. You can find some of the best goods in Hyrule there. It’s also the antithesis of the Great Calamity’s destruction: rather than finding previous towns decimated into ruins, Tarrey Town is the face of the new Hyrule rising from the ashes.

Finding the Hylian Shield. From the beginning, I hoped that the Hylian shield would be available somewhere in the game. I didn’t find it until the end of the game, but when I did, the shield was righteous.

Zelda’s face at the end of the game. #worthit

a87b59737f442d9c36c5eea72d68f923984f6f79_00

How is she 117 years old?

Finding out the location of Paya’s birthmark. Paya is probably my favorite character in the game. She’s a sweet, innocent Sheikah lass with a monster crush on Link. She will tell you she got her name from a papaya-seed-shaped birthmark somewhere on her body, but she won’t say where. I spent the whole game wondering where that birthmark was. Forget defeating Ganon and saving the princess, I just wanted to know. After finally completing the heirloom shrine in Kakariko Village (which was my last shrine because I overlooked the diary), Impa finally tells you.

5ynciqb

And now we know.

Some Critique

Although BOTW is marvelous, there were a few things I felt could have been improved. These critiques do not in any way mean that the game was poor.

It rains too much in Hyrule. Wanna go climbing? Nope – it’s a slip ‘n slide. Need to cook some food on-the-go? Sorry – flame goes out. Stuck waiting for time to pass? No sitting by a fire. Trying to explode a powder keg on some Bokoblins? Not today. And let’s just hurl some lighting bolts at you while you cross an open field, too. The rain does nothing but block your progress. My biggest frustration was climbing: I couldn’t explore the areas I wanted to go, and I couldn’t pass the time with a fire. Coming back later would be a hassle because I had already climbed high to get there, so I was effectively stuck. It would have been nice to have some sort of item to climb in the rain.

The weapons break too easily. The game mechanic of weapons breaking is pretty clever because it forces the player to always try new weapons. However, it feels like they break too soon. Weapon durability is a significant problem early in the game, because the player has very few inventory slots and strong weapons are hard to find. Later in the game, this is less of an issue. I think some better balancing could have been done.

There was no fishing rod. For being such an outdoorsy game, I was truly surprised that there were no fishing rods in BOTW. Link hunts deer with bows and arrows, but he needs to use bombs to catch fish? This struck me as strange and, to a small extent, thwarted the immersive feeling of surviving in the wild. A fishing rod may have been challenging to implement, but I think it could have been possible as a key item like the glider.

I craved more story points. Much of my gameplay narrative shifted between Divine Beast sagas and open exploration. At times, I felt like there was too much to explore without enough reward. I found myself avoiding enemy hideouts late in the game because I simply didn’t need their weapons or spoils. Having more memories to discover would have been awesome, though I suppose that’s what the DLC is for.

Behind the Scenes

Nintendo released a 4-part video series entitled The Making of The Legend of Zelda: Breath of the Wild that’s really cool. Video links are below.

Final Impression

I love The Legend of Zelda: Breath of the Wild. I can’t wait to see where Nintendo takes the franchise from here!

Why Choose BDD Over Other Test Frameworks?

People are heavily opinionated about Behavior-Driven Development. I frequently hear opponents say things like this:

Why would I use a BDD test framework instead of a traditional test framework like JUnit, NUnit, or pytest? The extra layer of plain language Gherkin steps gets in the way of the automation code. I can directly write code for those steps instead. BDD frameworks require lots of extra work that just doesn’t seem to add value. My team isn’t doing behavior-driven development practices, anyway.

I can sympathize with these sentiments, especially for those who have participated in projects where BDD was done poorly. Even if a team isn’t doing full behavior-driven development practices, I still assert that BDD test automation frameworks are better than traditional test frameworks for most feature testing (above-unit, black box). Here are reasons why.

Separation of Test Cases from Test Code

Test cases and test code are separate concerns. I should be able to design, discuss, and digest a test case without ever touching code. We describe features in plain language, and so we should also describe tests in plain language. Step definitions are nothing more than the automation behind the test case steps. Traditional test frameworks simply don’t have this separation of concerns, even if test methods are loaded with comments.

Guide Rails

BDD frameworks enforce good structure and layers for automation. There are designated places for test cases, step definitions, and support classes. The framework encourages good practices. Traditional test framework, however, are much more free-form. Programmers can do scary and stupid things with test classes. Functionally, a traditional test framework can still be structured well with layers and support classes, but it’s not required. Based on my experiences seeing less experienced automationeers shoving everything into Frankenstein’ed test methods, I much prefer to have the guide rails of a BDD framework.

Inherent Reusability

Steps are the building blocks of test cases, and test cases almost always have the same steps. BDD frameworks identify the step as a unique concern. One step with its definition can be used by any scenario, and steps can be parametrized for flexibility. This creates a “snowball” effect once enough steps have been developed: new tests may not require any new automation code! Traditional test frameworks simply don’t have this mechanism. It could be implemented by calling functions and classes outside of test classes, but not all automationeers are disciplined to do so, and everyone who does it will do it differently.

Aspect-Oriented Controls

Good frameworks handle cross-cutting concerns automatically. Things like logging, dependency injection, and cleanup shouldn’t interfere with test cases. BDD frameworks provide hooks to insert extra logic for these concerns around steps, scenarios, features, and even the whole test suite. Hooks can squeeze into steps because the framework is structured around steps. For example, hooks can automatically log steps to Extent Reports, instead of forcing programmers to write explicit logging calls in each test method.

giphy

The HOOKS, me bucko!

Easier Reviews

Nothing ruins your day like an illegible code review on features you don’t know. You are responsible for providing valuable feedback, but you can’t figure out what’s going on in the short amount of time you can dedicate to the review. Good Gherkin, however, makes it easy. A reviewer can review the test case apart from any code first to make sure it is a good test case. At this level, the reviewer could even be a non-technical person like a product owner. Then, the reviewer can either send the test case back with suggestions or, if the test case passes muster, dig deeper into the automation code.

Easier Onboarding

It can be hard to onboard new team members. They have so much to learn about the product, the code base, and the team practices. If tests are written using a BDD framework, then newbies can learn the features simply by reading the behavior specs. New automationeers likewise can rely on existing steps both for reuse and for examples as they develop new tests.

Other Reasons?

I’m sure there are other benefits to BDD frameworks, but these are the big ones for me. It’s an opinionated thing. Feel free to add comments below!

Are Multiple Scenario Outlines in a Feature File Okay?

Recently, someone asked me:

In Gherkin, is it good or bad practice to have multiple Scenario Outlines with Examples tables in one feature file?

The short answer is yes, it is perfectly fine to have multiple Scenario Outlines within one feature file.

However, the unspoken concern with this question is the potential size of the feature file. If one Feature has multiple Scenario Outlines with large feature tables, then the feature file could become unreadable. Remember, Gherkin is a specification language, not a programming language. A feature file should look more like a meaningful behavior example than a giant wall of text or a low-level test script. Make sure to follow good Gherkin guidelines:

  • Follow the Golden Gherkin Rule: Treat other readers as you would want to be treated.
  • Follow the Cardinal Rule of BDD: One scenario, one behavior.
  • Write declarative steps, not imperative ones.
  • Try to limit the number of steps in each scenario to single digits.
  • Use only a few rows and columns per example table.

Use, but don’t abuse, the templating facet of Scenario Outlines!

The Panda’s Dozen: Top PyCon 2018 Talks

There were tons of great talks at PyCon 2018 – more than I could attend in person – that are now available on the PyCon 2018 YouTube channel. This post has links to my favorites. Enjoy!

Check out PyCon 2018 Reflections to read my personal reflections, too. Watch my talk, Behavior-Driven Python, too!

By the Numbers: Python Community Trends in 2017/2018 (Dmitry Filippov, Ewa Jodlowska) – At the end of 2017, the Python Software Foundation teamed up with JetBrains to conduct an official Python Developers Survey. Data science is taking Python by storm, and Python 3 now has majority adoption. There are tons of other cool statistics, too!

How Netflix does failovers in 7 minutes flat (Amjith Ramanujam) – That speed at that scale is mind-blowing. This is a fascinating talk, even for non-engineers!

Solve Your Problem With Sloppy Python (Larry Hastings) – “If you ever start writing a shell script, delete it and write a Python script instead.” This talk is a jovial reminder that Python is a powerful tool, even for hack-n-slash jobs.

The AST and Me (Emily Morehouse-Valcarcel) – Emily gives a great overview of the inner workings of the Python language. This talk is a must-see for anyone into compiler theory.

Dataclasses: The code generator to end all code generators (Raymond Hettinger) – Dataclasses are new data structures to Python to generate classes based on specs.

Pipenv: the Future of Python Dependency Management (Kenneth Reitz) – Pipenv is a new tool that makes pip, Pipfile, and virtualenv easier to use together. Kenneth gives a good overview of Python packaging and why pipenv is awesome.

Type-checked Python in the real world (Carl Meyer) – Sometimes, I wish Python had static typing. Now, it can! Facebook has done some innovative things to make it possible.

Beyond Unit Tests: Taking Your Testing to the Next Level (Hillel Wayne) – Property tests + contracts = integration tests. Hillel gives a fantastic strategy for making tests smarter.

“WHAT IS THIS MESS?” – Writing tests for pre-existing code bases (Justin Crown) – This is a pragmatic guide to adding new tests to old code. Now, you’ll never procrastinate on your tests again!

Demystifying the Patch Function (Lisa Roach) – Mocking is a great practice for limiting scope in unit tests. Whether using unittest.mock or other patching/mocking packages, this is a great talk for learning why and how to do mocking in unit tests!

Automating Code Quality (Kyle Knapp) – One of Python’s most beloved traits is its elegance. Maintaining high standards of code quality can be challenging for large projects, though. Kyle shows how to use existing tools to drive higher quality.

Keynote (Ying Li) – [35:07] – Ying is a software security engineer at Docker. In her keynote, she urged all people involved in technology to learn the basics of security. Definitely watch the video recording – she used a fun story to illustrate her points.

Keynote: The People and Python (Qumisha Goss) – [1:07:35] – “Q” is a librarian at the Detroit Public Library who taught herself Python so she could teach coding classes to kids. She shared the highs and lows of her experiences, especially in light of many disadvantages her students had. My favorite takeaway was to “cultivate greatness in others.”