fun

PyOhio 2019 Reflections

PyOhio 2019 was one of my favorite conferences, ever. It was my ninth Python conference and my second PyOhio conference. There were so many good things that happened in such short time that, even three weeks later, I’m still processing everything. Here are my reflections on this outstanding conference.

Roadtrip

PyOhio 2019 was held in Columbus, Ohio at the Ohio State Union. I really wanted to go because PyOhio 2018 was such a good time, and I started asking my friends in North Carolina if anyone wanted to join me. My friends Rick and Justin all emphatically replied YES! To make traveling more fun, we decided to turn it into a road trip! We dubbed ourselves the “PyCarolinas delegation”, piled into my Chrysler 300, and made the 8-hour drive in good time. Our friend Greg also joined us at PyOhio, though he traveled separately with his wife.

This was the first time I ever did a road trip to a conference. I’m so glad we did it. I felt like I got to spend great quality time with my friends. Many parts of the drive were quite scenic. We also discovered a Beef Jerky Outlet!

My Talks

At PyOhio 2019, I delivered the holy trifecta of speaking opportunities: a talk, a tutorial, and a lightning talk. I felt both honored and humbled to be chosen for all three.

My talk was entitled Surviving Without Python. I talked about how we can use Python’s principles, projects, and people to inspire us even when we don’t use Python to solve our problems:

My tutorial was entitled Hands-On Web UI Testing. Python’s popularity continues to rise, and many people use it for testing. In my tutorial, I showed how you can develop a simple yet powerful solution with Python, pytest, and Selenium WebDriver to automate Web UI tests. The tutorial project in GitHub contains the code, instructions, and slides.

My lightning talk was announcing PyCarolinas 2020. My friend Calvin and I are teaming up to bring PyCarolinas back! We are targeting June 2020 in Raleigh, NC. Please help us make it happen!

Other Talks

There were so many great talks at PyOhio. Here were a few highlights.

This was my favorite talk of the conference. Although a history lesson may seem out of place at a Python conference, Jon used it as a convicting call to action. Be sure to watch it to the end!
Dane showed how easy it is to use pytest. You don’t need to be an expert tester to write good tests!
Travis blew my mind with some of Python’s latest features. This talk was a great way to catch up on new things!
Dustin explained why it’s important to keep alive the passion we have for computing. I also loved the TI-83 Plus reference – that was in my talk, too!
Controversial? Yes. True? Yes. Aly? Preach!
Docs are vital for understanding code and features. Mason shows how to make docs just a regular part of the development process.

Sprints

Sprints are a Python conference event in which people work together on open-source projects. Conferences are the perfect time to have sprints because people are both co-located and excited. PyOhio 2019 was actually the first time I attended sprints. There were sprints on both Friday and Saturday nights. Accenture graciously hosted both sprints in their swanky office and provided refreshments.

I went to the sprints both nights with the honest intention to work on stuff. However, I spent the whole time socializing with friends. It was nevertheless time well spent! Many of us went to Jeni’s Splendid Ice Creams after the final sprint, too.

Swag

The PyOhio 2019 logo was lit! I joked that I was going to the conference just to get that logo sticker and t-shirt. Some other cool takeaways were the Numerator puzzles and the JP Morgan Chase puzzle blocks.

My sticker game is strong:

My backpack was also a hit!

Food and Drink

I had some good eats while in Columbus. My friend Mason recommended Raising Cane’s, which turned out to be awesome! So many people followed us there, too.

I also hopped an electric scooter to get bubble tea. Those scooters are so much fun. I hadn’t ridden one since PyTexas 2019! (Or maybe PyCon 2019; I don’t remember precisely.)

To relive PyOhio 2018 memories, I went to Eden Burger for a Vegan brunch on Sunday morning with friends! It was delicious and nutritious.

Our friend Greg recommended we visit Brewdog, a renowned Scottish craft brewery with a huge site on the outskirts of Columbus. We took the tour with the “beer school” course, and we stayed for a delicious dinner afterwards. So good, so very good. It was the best way to end the conference!

Friends

The best part about PyOhio 2019 was the time I spent with all my friends. I wish I could name everyone here, but there are just too many names. The Python community is the best. Conference friends are real friends. Also, for what it’s worth, they’ve given me the nickname “Pandy.”

Hope

My PyOhio 2019 experience can be summarized in one line:

Truth – I went all-in from leaving my house on Friday morning until returning Monday evening. The conference high is very real. My hope is that I’ll get to attend more great conferences like this, and also that I’ll be able to help make PyCarolinas as good as PyOhio!

Surviving Without Python


Python is such a popular language for good reason: Its principles are strong. However, if Python is “the second-best language for everything”… that means the first-best is often chosen instead. Oh no! How can Pythonistas survive a project or workplace without our favorite language?

Personally, even though I love Python, I don’t use it daily at my full time job. Nevertheless, Pythonic thinking guides my whole approach to software. I will talk about how the things that make Python great can be applied to non-Python places in three primary ways:

  1. Principles from the Zen of Python
  2. Projects that partially use Python
  3. People who build strong, healthy community

Check out my talk, Surviving Without Python, from PyOhio 2019! It was one of the most meaningful talks I’ve ever given.

How To Be A Great Airbnb Guest In 12 Steps

My wife and I have been proud Airbnb hosts since 2018. We currently host three guest suites between two properties in North Carolina, and we love doing it. Airbnb enables us to take care of my wife’s mom and afford critical house renovations. Overall, hosting has been a worthwhile, albeit sometimes tiring, experience.

Between our three listings, we see many guests. We try to be “super” hosts to every guest who stays with us, and most of our guests likewise try to be super guests. However, nobody is perfect. While we believe that the vast majority of Airbnb users want to be good, not everyone may be cognizant of irksome or even damaging missteps. From our perspective as hosts, we’d like to share 12 ways for good guests to be truly great guests.

#1. Share information about yourself and your travel plans.

As hosts, we don’t know who you are. You are strangers who we meet online, and you want to stay at our house. We want to trust you, but help us! Don’t be shy. Update your Airbnb profile with your email, phone number, and information about yourself. Share your actual profile picture – not a picture of your kids or some dumb cartoon sketch. Upload a copy of your government ID. When you request to stay at our place, share why you are traveling. Tell us when you plan to arrive and leave, and tell us exactly who all the guests will be. Ask us for local recommendations.

The more you share about yourselves, the more likely we will be as hosts to accept your request to stay. Conversely, we have also rejected requests when guests don’t upload their IDs or when they aren’t forthright with information.

#2. Read (and follow) all house rules and guides.

When guests request to stay at a listing, they must agree to follow all house rules (in addition to Airbnb’s policies). House rules are attached to the listing and accessible before booking. Our house rules are pretty basic, but we frequently see the following violated:

  • No shoes inside.
  • Park on the street, not in the driveway.
  • Quiet hours after 10pm.

Breaking these rules is not a huge problem but unfortunately reveals guests to be careless and disrespectful. Read the rules before you book.

Similarly, read the guides before you check in. We provide a full step-by-step guide with pictures for each listing, including the entry codes. We also provide WiFi and Netflix information. Asking us for the combo code or trying to enter the wrong door reveals that guests did not prepare.

#3. No means no.

Hosts set rules for reasons. Guests should not expect exceptions. For example, we do not allow children under age 12 in any of our listings because they are not baby-proof or child-proof. We have fragile decorations, furniture with sharp edges, and outlets without safety covers. We also do not allow pets because I am allergic to animal dander. These rules are published clearly on our listings. Please do not request to stay with us if you intend to bring a child or a dog. Please do not ask for an exception because “he’s a good boy.” Or worse, don’t show up with a rule violation and put your host in an awkward situation. It’s okay to ask for things that are unclear or unspecified, but please be reasonable with requests, and do not be offended if the host says no.

#4. Include all guests in the booking.

Each listing has a maximum number of allowed guests. When guests book a listing, they must include how many people will come. Guests should list all people, but unfortunately that doesn’t always happen. It’s common for a guest to book for one person and then have more show up. This may or may not be a serious problem. For example, one of our suites can accommodate 3 people, but we charge extra per night because we need to turn a futon into a bed. We’ve had guests book it for one person and then have three show up – creating an awkward situation. We also had one problematic guest invite five or six others over without even asking. As a guest, just make sure to include all members of your party in the booking, and ask for permission before bringing over someone not in the booking.

#5. Cancel early (when necessary).

Cancellations are always disappointing for hosts, but we understand that plans change. If you as a guest need to cancel your reservation, then please cancel as soon as possible. Every day you hold a reservation is an opportunity cost for someone else to book. When a guest cancels late, the host loses the income and has little chance to find a replacement.

Furthermore, respect the host’s cancellation policy. Hosts choose one of Airbnb’s standard policies, so make sure to check the listing when you book. If you cancel too late and don’t get a full refund from Airbnb, then please don’t feel entitled to get a full refund directly from the host.

#6. Treat the space well.

As hosts, we put a lot of work into making our guest suites nice. We carefully choose the furniture and decor. We clean the suites thoroughly between stays and inspect them for any problems. And we tend to cycle through many guests in short time. Our guest suites need to “survive” day to day.

As guests, please take care of the spaces you rent. Be careful not to cause any damages. Clean up your messes. Wash your dishes. Hang up your towels. Don’t leave food out for bugs. Overall, just think about how you’d want a guest to treat your home.

#7. When in doubt, ask for permission.

Grace Hopper once said, “It is easier to ask forgiveness than it is to get permission.” However, this is terrible advice for Airbnb rentals! Guests should always ask their hosts whenever the rules or guides are unclear. My wife and I are fairly accommodating with most requests, such as late checkin or storing food in our fridge. We just don’t like surprises – like someone unexpectedly cooking during our family mealtimes.

#8. Don’t do sketchy things.

Airbnb stays are meant to be a fun, safe experience for both guests and hosts. There should be an implicit sense of trust between guest and host. Neither party should participate in illegal or discomforting activities. Drugs, sex work, and pornography are unwelcome – and not to mention a violation of Airbnb’s policies. If you are a guest, don’t do these things. My wife and I have kicked out guests for doing sketchy things.

Also, be clear and open about your intentions, especially if they are atypical. If you need to stay up late to work on a project, let your host know so they don’t wonder why your lights are on all night. If you need to bring large medical hardware, let your host know so they don’t think you’re “Breaking Bad.” If you want to use the listing for a family photo shoot, let your host know so they don’t suspect you of filming porn. Remember, you are staying in another person’s space. Please don’t make them worry.

#9. Be patient when problems happen.

Problems happen. Even though hosts work really hard to make things perfect, sometimes they overlook details, and other times things are out of their control. Our guest suites have had problems with temperature, hot water, burned-out light bulbs, and even bugs.

As guests, please be gracious with problems. Tell your host right away. Good hosts will want to fix the problems ASAP. Share pictures so your host can see exactly what is wrong. Be polite, not belligerent or whiny. Please be patient while the host works to fix the problems. And don’t wait until the final review to share a problem. By then, it’s too late. Guest shouldn’t suffer and hosts shouldn’t get bad reviews when problems can be fixed.

#10. Be honest when you cause problems.

Again, problems happen. Here’s a few we’ve seen:

  • Guests parked in the driveway and blocked our cars.
  • Guests tracked mud into the house.
  • Guests spilled coffee on the bedroom carpet.

Good hosts will focus on solutions rather than blame. As guests, please take responsibility for any problems you cause and help work toward solutions. Be quick to respond to your host, and be willing to pay the host for any damages. For example, the guest who spilled the coffee reimbursed us about $10 for carpet cleaner.

#11. Check out on time.

Good listings have high occupancy rates. All three of our suites are typically 75-100% occupied every month. Whenever a guest checks out, a new guest will probably check in later that same day. As hosts, we need to flip the space in that short window between checkout and checkin. That includes inspecting, vacuuming, cleaning, laundry, remaking the bed, and handling any surprises.

Please make sure to check out punctually. Tell your host ahead of time when you plan to check out, and send the host a message to let them know when you leave.

On a related note: the most common request from our guests is for an early checkin time. We try to accommodate early checkin for guests who ask, but we cannot make guarantees. An early checkin time depends directly upon the previous guests’ checkout time.

#12. Don’t leave poor reviews for poor reasons.

At the end of a stay, the host and the guest review each other. Reviews are kept private until either both parties submit them or 14 days pass. The bidirectional nature of reviews holds guests and hosts equally accountable to each other, which encourages better behavior from both sides.

I encourage everyone – guests and hosts alike – to give truthful, transparent reviews. A robust review system keeps the Airbnb platform trustworthy. At the same time, be mindful about what you write in your reviews. Hosts rely upon good reviews for income, and bad reviews – even 4 stars instead of 5 – can be especially damaging. If you leave a bad review, make sure it is for a good reason. Nothing is more frustrating than to see reviews like these:

  • A guest said everything during their weekend stay was absolutely perfect. They adored the location, the decor, and the coffee machine. They said they’d definitely come back. No negative comments. 4 stars instead of 5.
  • A guest gave 3 stars for accuracy because the guest suite didn’t have a private entry, even though the listing explicitly stated that there was no private entry.
  • A guest complained that one of the bedsheets was upside down and not tucked in perfectly.

Thankfully, off-the-mark reviews like these happen rarely. I’m sure some hosts are guilty as well. Please don’t give poor reviews for poor reasons.

Final advice

There are many more things we could share, but the “golden rule” comes down to this: Be a good guest to every host, just as much as you want your host to be good to every guest. Even if your host is lousy, still strive to be a good guest for your integrity and the integrity of other Airbnb users.

PyOhio 2018 Reflections

PyOhio 2018 was a free Python conference hosted at Ohio State University in Columbus, OH from July 28-29. I had the pleasure of not only attending but also speaking at PyOhio, and my company, PrecisionLender, graciously covered my travel expenses. I had a great time. Here’s my retrospective on the conference.

My Talk

The main reason I went to PyOhio was because I was honored to be a speaker. When I was at an Instagram dinner at PyCon 2018, I met a few conference organizers who encouraged me to propose talks at other Python conferences. On a whim the next morning, I spitballed an idea for a talk about building a test automation solution from the ground up in Python. After talking with a number of people, I realized how test automation is such a struggle everywhere. I took inspiration from Ying Li’s keynote and crafted a story about how Amanda the Panda, a Bamboozle employee, becomes a test automation champion. And, BOOM! My talk proposal was accepted for PyOhio and PyGotham! The video recording for my talk, “Egad! How Do We Start Writing (Better) Tests?”, is below:

Arrival

Good news: Raleigh and Columbus have direct flights. Bad news: they are either early-morning or late-night direct flights. So, I left Raleigh on Friday morning before the conference and spent the day in Columbus. Surprisingly, the security line at RDU wrapped around 2/3 of the Terminal 2 perimeter, but I still boarded the flight on time. Once I landed in Columbus, I took the COTA AirConnect bus downtown for the low price of $2.75.

My goal for Friday was personal development. I rarely get a chance to escape the rigors of everyday life to focus on myself. Personal retreats let me clear my mind, dream big, and begin taking action. And on this day, I started writing my first test automation book – a dream I’ve held for over a year now. I spent a few hours at Wolf’s Ridge Brewery, sampling beers with lunch as I developed a rough outline for my project.

My evening was low-key. I took a nap at my hotel, the Blackwell Inn and Pfahl Conference Center. For dinner, I ate at White Castle for the first time – and it was pretty darn good. After practicing my talk, I got a tiramisu bubble tea from Vivi as a night cap.

The Conference

PyOhio was a much smaller conference than PyCon. There were fewer vendor tables but nevertheless a wide selection of stellar talks. As a result, the conference felt more intimate and more focused. Perhaps that feeling was due also to the venue: the third floor of the Ohio Union had full rooms with “cozy” hallways. Hats off to the organizers, too – everything ran smoothly and professionally.

As soon as I arrived, I scored my name badge, my swag bag, and my official PyOhio 2018 t-shirt. The opening keynote from Adrienne Lowe, “From Support to Engineering and Beyond: What to Take with You, and What to Leave Behind,” about the highs and lows of trying to make it as a developer was exceptionally inspiring. Engineers often don’t talk about how hard the job is, especially for newcomers to the industry. Everybody suffers from imposter syndrome. Everybody feels inadequate. Everybody is tempted to quit, even to the point of tears. The vulnerability in hearing others say, “Me, too,” is so relatable and so relieving.

The first talk-talk I attended was Trey Hunner’s “Easier Classes: Python Classes Without All the Cruft.” Trey gave an excellent overview of writing more sophisticated Python classes. TL;DR: upgrade to 3.7 and use dataclasses.

The next talk I attended was Leo Guinan’s “Go with the Flow: Automating Your Workflows with Airflow.” Apache Airflow is a platform for automating workflows. As an automationeer, it struck me as being like a continuous integration system generalized for non-build purposes. The Q&A portion of the talk was lit.

After finding an authentic Chinese restaurant for lunch, my friend Matt arrived! I worked with Matt in the testing space at LexisNexis. He drove all the way from Dayton to see my talk and hang out. We spent the early afternoon catching up, and we went to Hook Hearted Brewing for dinner after the conference because we’re beer buddies. I was so thankful he came to support me – it meant a lot!

My talk was at 3:45pm. Other than discovering my Thunderbolt-to-HDMI adapter was a dud, the talk went very well. I decided to stick to a script for this talk because most of it followed a story, and I’m glad I did. (For my PyCon talk, I chose instead to speak without a script and rely instead on the slides alone.) There were about 30 people in the audience. Many expressed appreciation for my presentation!

The last talk of the day for me was Jace Browning’s “Automated Regression Testing with Splinter and Jupyter.” It was the perfect follow-up to my talk. Whereas mine was mostly high-level, Jace showed implementation and execution. I loved how he compared raw Selenium WebDriver calls to splinter calls, and I was thrilled to see hands-on test execution using Jupyter. One of the things that makes Python so great for automation is that modules can be called from the interpreter – and Jupyter notebooks make that so easy.

The Second Day

Sunday was a shorter conference day. The opening keynote, Lorena Mesa’s “Now is better than Never: What the Zen of Python can teach us about Data Ethics,” didn’t start until 11:40am. Lorena showed us what the Zen of Python can teach us about data ethics in a scary, modern world.

I got lunch at Chatime: dan dan noodles (or rather, an imitation thereof) and a matcha latte with grass jelly. Yum! After lunch, I attended Daniel Lindeman’s “Python in Serverless Architectures.” Now I know what the buzzword “serverless” means! I even found out that I had already developed a serverless app using Django and Heroku. There are some really cool ways test automation could take advantage of serverless architectures.

Another one of my favorite talks of the afternoon was Vince Salvino’s “Containers Without the Magic.” Vince broke down how easy containers are to use. It was a great refresher for me.

Open Spaces

At 3:15 on Sunday, I tried something new: I hosted an open space for test automation. “Open spaces” are rooms that can be reserved for a time slot to meet up informally about a common interest. (For example, PyCon had a juggling open space!) At first, nobody showed up to my open space, but after a few minutes, one lady walked in. She had been a software tester for years and wanted to start doing automation. I walked her through as much info as I could before time was up. She was very grateful for the guidance I offered. It worked out nicely that she was the only person to come to my open space so that she could really get value out of it. (My friend Jason also popped in and helped out; more on him below.)

The After-Party

At conferences, my biggest fear is being awkwardly alone. I want to spend time with good people, both new and familiar. Thankfully, PyOhio didn’t disappoint.

Backstory: At PyCon 2018, I met a guy named Julian who runs PyBites (together with his buddy Bob). We really hit it off, and he invited me to join the PyBites community. They offer great code challenges and a “100 Days of Code” challenge course, as well as a blog about all things Python. Through the PyBites community, I met another guy named Jason who would be at PyOhio 2018 with me. We agreed to meet up for dinner and drinks after the Sunday talks.

(On a side note, I recommend PyBites as a great place to learn new things, hone skills, and meet great people!)

That Sunday night, it just so happened that Adrienne and Trey, two of the other speakers, intersected Jason and me as we were deciding where to go for dinner. The next thing we know (after a hotel pitstop), we’re all walking off together to Eden Burger, a local vegan burger joint. I had a vegan “cheeseburger” with fries and a “milkshake” – and they were genuinely delicious! More than the food, I enjoyed my time with new friends. I was really inspired by the cool things each of them is doing. I guess that’s Python conference magic!

Jason and I hit World of Beer after dinner. After Slack-ing for weeks, it was so good to spend time with this fine gent. We discussed Python, software, our careers, our families, and our dreams. What a perfect way to conclude PyOhio 2018!

Takeaways

There were so many takeaways from PyOhio 2018 for me:

  1. Conferences are phenomenal for professional development. The pulse I get from conferences is electrifying. I walked away from PyOhio galvanized to be an even better software engineer. The talks opened up exciting new ideas. Inspiration for several blog posts sprang forward. The people I met motivated me to try new things. I got so much vigor out of such a short time.
  2. My friends around the globe are awesome. Matt, Jason, Adrienne, Trey, Julian (vicariously), and all the other great people I met at PyOhio made my conference experience so rewarding.
  3. Good values foster wonderful communities. My company, PrecisionLender, has four major values: Be helpful, humble, honest, and human. Those values make my company such a great place to work. I see those same values in the Python community, too. People at PyOhio even asked about these values when they saw them on my PL shirt and my business card. I think that’s partially why Python conferences are always so welcoming and inspiring.
  4. Bigger conferences have more pizzazz, while smaller conferences are more intimate. PyCon 2018 was big, flashy, and awesome. I scored so much swag that I nearly couldn’t fit it all in my suitcase to carry home. PyOhio 2018, on the other hand, focused much more intently on the talks and the people. A perfect example of this was Leo Guinan’s monologue-turned-dialogue on Airflow: it was natural for people to just ask questions. Both types of conferences are good in their own ways.
  5. PyCon 2018 was likely a watershed moment for my career. I cannot reflect on PyOhio 2018 without seeing it as an extension of my PyCon 2018 experience. The only reason I attended PyOhio was because someone at PyCon encouraged me to propose a talk. The reason I met Jason is because I first met Julian. The reason I want to keep speaking is because PyCon went so well for me. The fact that both conferences were hosted in Ohio only two months apart is also rather serendipitous. Like my first trip to China, I think PyCon 2018 will have a lasting impact on my career.

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:

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!

Tutoring: A Lifelong Impact

On Saturday, February 17, 2018, I delivered the keynote address at RIT TutorCon 2018 at the Rochester Institute of Technology in Rochester, NY. I was a student tutor at RIT from 2007-2010. The Academic Support Center asked me to speak about my experiences. Below is the transcript of my speech.

It’s good to be back in Ra-cha-cha! Happy Presidents’ Day weekend, and also Happy Chinese New Year! Let me get a good look at our tutors: If you are a tutor, please stand up.

[Wait for tutors to stand up.]

Great! It’s awesome to see so many of you here today. Is anyone in Computer Science?

Now, remain standing if you have been a tutor for at least one year.

[Wait for people to sit down.]

Not bad. What about two years?

[Wait for more people to sit down.]

Three? [Wait.] Four? [Wait.] Five? [Wait.]

What about ten years? Ten years of tutoring? [Give anyone who remains standing a round of applause, and then ask them to sit down.]

Ten years is a long time! A lot can happen; a lot can change. Here’s a question for you today, though: Will your tutoring make an impact in ten years? [Repeat the question for emphasis.]

Ten years ago, I was one of you. I was in my second year at RIT studying computer science, and I worked for the Academic Support Center and TRIO as a tutor for math, physics, and basically anything that was needed. I would have been sitting in your chair if we had these fancy tutoring conferences back them. Things were quite different a decade ago. Let me drop some knowledge bombs on you for the world in February 2008:

  • We were still on the iPhone 1. iPads did not exist yet.
  • Barack Obama was still seen as a surprise challenger to Hillary Clinton in the 2008 Democratic primaries.
  • The Great Recession was looming but had not yet hit.
  • The Summer Olympics were going to be held in Beijing, China. (Michael Phelps & Usain Bolt)
  • Lady Gaga had not yet released her debut album.

Now, let me contextualize this for RIT:

  • Bill Destler was still in his first year as university president.
  • RIT was still on the quarter system.
  • Park Point was being built.
  • The Simon Center (a.k.a. the “Toilet Bowl”) was being built.
  • The main drop-in study center was the “Math Lab” in Building 1, not Bates.

One thing that looks like it hasn’t changed, though, is Gracie’s. [Assume the audience will laugh.]

By the way, have they knocked down Riverknoll yet? I lived at 232 Kimball Drive. [Assume the audience will laugh or somehow respond.]

A lot happens in ten years. But, will your tutoring have an impact in ten years? Will the tutoring you do today benefit your students years from now? It should.

As college students, life is typically fast-paced. You have classes, you have papers, you have projects; quarters – excuse me, semesters – fly by; and it’s all over after about four years. And, for you, tutoring is just a part of that overall experience. It’s just a part-time job. As we saw earlier, most of you will spend only a few years tutoring before entering your career fields. Personally, I haven’t done any tutoring since 2010. It’s tempting to think that the time you spent tutoring doesn’t matter. So what if you help people finish their homework problems a few times a week? Students come and go anyway. It’s no big deal, right?

Well, if you’re here today at this tutoring conference, I’m pretty sure that tutoring is a big deal to you. You know it’s important. I’d be willing to bet that many of you would do tutoring even if you didn’t get paid – although, the pay is certainly deserved! I want you all to understand that what you do as a tutor will impact your students and will also impact you for the rest of your lives. Tutoring is a vector: I want you to see the line and not just the dot.

Your students come with a myriad of different circumstances. Some are just looking for a healthy environment for doing their homework. Maybe they’re stuck on a tricky physics brain-buster. Others struggle. Some really struggle – and may be one more failure away from academic suspension. But all students have one thing in common: they come to you because they want to do better. Whoever they are, they look to you as tutors to help them succeed. And every question you answer – or rather, every guiding question you turn back to them – puts them further down their paths to success. Today’s practice problems become tomorrow’s degrees. With you, they’ll learn not just the course material but, more importantly, they will learn how to learn. They will learn what questions to ask themselves. They will learn how to find answers using their resources. They will learn to teach themselves. Plutarch once said, “The mind is not a vessel to be filled but a fire to be ignited.”

With my perspective of the line, I want to give you three big ways you can make your tutoring today leave an impact for a lifetime.

First, own your role. As tutors, you have a very unique role with your students: you are peers; you are not professors. That’s a big difference! Professors are experts in their fields with years of experience and dozens of publications. You, as tutors, are students yourselves, just a few more years ahead. You can relate to your students on much more common ground. You’ve taken the same courses. You’ve taken the same tests. You’ve probably even done the very same problems. One of the tutoring tricks is to always work with a student at their level – if they sit at the table, you sit; if they stand at the board, you stand; and unless you’re making a really good example, don’t stand on the table! The equal-level principle also applies to your role as a peer tutor. There’s camaraderie. There’s energy. There’s less embarrassment to ask “stupid” questions. There’s a sense that they can do it because you can do it. So own your role as a peer tutor.

Second, focus on the student and not the problem. The problem is the dot; the student is the line. Tutors aren’t there to solve the world’s problems! Nobody comes to a tutoring center to watch a tutor show off with how much they know or how fast they can solve problems. “Look at how smart I am” – NO! Let’s be real, here: the solution to any given practice problem doesn’t really matter. What does matter is how the student learned to handle problems. Did they make an attempt? Did they look at their formulas? Did they write out their work? Did they persevere when they got stuck? Let me ask you a question: Do you think that I remember specific details to any homework assignments from ten years ago? [Wait for audience response.] Nope! But, I remember that a derivative is a rate of change. And, if I had to solve a derivative again, I’d know exactly where to look in my books to figure it out. That’s how you want your students to be in ten years. Cultivate your students to become independent.

Third, build camaraderie. Your students are already your peers – make them your friends. I don’t have any fancy statistics to share, but I know anecdotally that most students become “repeat customers.” You’ll see them again, and again, and again. Whether intended or not, you will forge relationships with your students. As your tutoring shifts become part of your everyday life, so, too, do the students who show up. Treat every single one of them the way you’d want to be treated. Work to form good relationships. Work to form trust. Be honest when you don’t know something. And furthermore, build camaraderie with your fellow tutors as well! Tutors are a team – each one brings fresh eyes and unique expertise. My specialty? Discrete math and differential equations – what a combo! We, as tutors, are trained in common techniques and share the common burdens to help our students. It’s almost like we have a special, unspoken club. I still keep up with my students and my tutors. I dined with a former student on top of the Space Needle. I partied with another on New Year’s Eve. I’m attending another student’s wedding this summer. A fellow tutor came to mine. So build camaraderie with your students and your fellow tutors.

As I close, I’d like to remind you that you are all in tutoring together. For some of you, this might just be the best job you ever have. I challenge all of you today to make your tutoring count: for now, for ten years from now, and for a lifetime. Tutors don’t make bad students good – tutors make students learn to teach themselves. That is how your tutoring will make a lifelong impact. Thank you.

The Airing of Grievances: BDD

Behavior-Driven Development – one of my favorite blog topics. When done right, it’s a wonderful way to foster better collaboration and automation. When it’s not… well, let’s just say I got a lot of problems with bad BDD practices, and now you’re gonna hear about it!

PROCESS

Treating BDD as a Tool and Not as a Process

BDD is a process – it is a set of tools and practices designed to help teams deliver better software. BDD is not just a test automation framework; the framework is just one of the tools that support BDD. Heck, the word “development” is in the name!

Complaining that Gherkin is Too Technical

Really? Really!? Gherkin is basically just plain language with some buzzwords mixed in! It is specifically designed for non-technical people to handle it! It is not a full-fledged programming language – it is essentially a simple format for behavior specification that automation frameworks can easily parse. The steps are meant to be read like plain English (or any other spoken language) so that better collaboration can happen. If Gherkin is “too technical” for you, then I hate to know what isn’t.

No Buy-In from All Roles

The three major roles on an Agile team, a.k.a the “Three Amigos,” are biz, dev, and test (regardless of fancy names or assignments). For BDD to work well, all three role types must embrace it. Otherwise, collaboration will suffer. BDD is not just a QA thing, it’s for everyone. Biz gets better features in shorter time because requirements were communicated better. Dev wastes less time figuring out what biz wants and gets tests faster. Test can start automating right away since test scenarios are defined from the start in Gherkin. Everybody wins if everybody contributes.

No Three Amigos Meetings

Three Amigos meetings are like dietary fiber supplements: they help a team stay regular with collaboration, or else development gets constipated as engineers start building crap instead of the intended behaviors. Then the crap gets blocked up as the team must rework it, meaning it could be another sprint before there’s a healthy flush of new features. Open conversations in regularly scheduled Three Amigos meetings would have avoided the whole obstruction.

Forcing QA to Write All Behavior Scenarios

BDD is not just QA thing – it is for all roles. Pigeonholing the responsibility of writing behavior scenarios onto QA is not only unfair, it is anti-collaborative. The whole reason for writing scenarios in plain language with Gherkin is to let everyone contribute to feature behavior. Scenarios are primarily about capturing behavior, not writing tests. If tests were the main focus, then engineers could just write test cases using traditional automation frameworks directly in general purpose programming languages like Java or Python. BDD offers the benefits of process efficiency and shifting left when the whole team helps to write behavior scenarios.

GHERKIN

Bad Gherkin

Only you can prevent bad Gherkin. Or I can – via rejected code reviews.

Typos, Poor Grammar, and Inconsistent Formatting

Gherkin needs to be readable. Steps with typos, poor grammar, and inconsistent formatting will still run fine for test automation, but they make it tough to understand the behaviors they describe. Sometimes, they can even make the meaning ambiguous.

No Double-Quotes Around Step Parameters

How do you know if something is a step parameter? “Double quotes” make it easy. However, Gherkin does not enforce double quotes around parameters. It is merely by programmer’s convention, but it’s a really helpful convention indeed.

No Tags

Tags make it super easy to filter scenarios at runtime. No tags? Good luck remembering long paths and names at runtime, or running related scenarios across different feature files together.

More Than 120 Characters per Line

Any longer is too much to comprehend. Either write the step more concisely, or split it apart. Plus, the line may go off the edge of the screen.

More Than 10 Steps per Scenario

Again, any longer is too much to comprehend. Scenarios should be short and sweet – they should concisely describe behavior. Too many steps means the scenario is too imperative or covers more than one behavior.

Multiple Behaviors per Scenario

Scenarios should not have multiple personality disorder: one scenario, one behavior. Don’t break the Cardinal Rule of BDD! So many people break this rule when they first start BDD because they are locked into procedure-driven thinking. Then, when tests fail, nobody knows exactly what behavior is the culprit. One scenario, one behavior.

Out-of-Order Step Types

Givens, Whens, and Thens each serve a specific, ordered purpose: Given some initial state, When actions are taken, Then verify an expected outcome. Jumbling them up ruins their meaning. Furthermore, duplicate When-Then pairs indicate multiple behaviors per scenario. And don’t just reassign step types to skirt the strict-ordering rule. Do it right – put integrity into the steps!

Gigantic Tables

Have you ever seen an Examples table with 13 columns? Or maybe 517 rows? I have. The horror, the horror! Tables that big make scenarios lose any semblance of specification-by-example. Make sure table rows and columns are actually needed. Use key-value lookups if the data is too gritty.

Being Imperative Rather Than Declarative

Given I’m logged into the app, when I click here, and I click there, and I type P, and I type L, and I type E, and I type A, and I type S, and I type E, and I type D, and I type O, and I type N, and I type T, and I type W, and I type R, and I type I, and I type T, and I type E, and I type S, and I type C, and I type E, and I type N, and I type A, and I type R, and I type I, and I type O, and I type S, and I type L, and I type I, and I type K, and I type E, and I type T, and I type H, and I type I, and I type S, then go directly to jail, and do not pass GO, and do not collect $200. Steps should focus more on what than how.

Prefixing Existing Test Procedure Steps with Gherkin Buzzwords

Let’s just take our existing test procedures from a tool like HP QualityCenter or ALM and put the words “Given,” “When,” and “Then” in front of every step. Ta-da! We’re now doing BDD! …WRONG!! I kid you not, I have see this happen. These people clearly never took BDD 101. It hurts to see.

AUTOMATION

Unorganized Step Definitions

Programmers like to throw their step definition methods anywhere. Add ’em to an unrelated existing class? Create a whole new class for only two new steps? Mix up the types? Who cares! Don’t bother to alphabetize them, either. Well, that’s how tech debt happens. That’s how duplicate steps get written, because originals can’t be found. Imagine a library without the Dewey Decimal System – that’s what an unorganized step def collection will be.

Putting Cleanup Code in Then Steps

Cleanup code belongs in After hooks, where it will be run no matter what fails during the scenario. Writing Then steps to do cleanup not only breaks step type integrity, the cleanup code will not run if a previous step aborts!

Catching and Burying All Exceptions

Here’s something I see all the time in automation code (and not just for BDD):

// FYI - This is Java, but the same thing can happen in any language
@When("^do something$")
public void doSomething() throws Throwable {
  try {
    callStuff();
  }
  catch (Exception e) {
    System.out.println(e.getMessage());
  }
}

The entirety of a step (or even a whole test) is surrounded by a try-catch that catches every exception. THIS STEP CAN NEVER REGISTER A FAILURE! Even if there was a failed assertion or, worse, an exception that ought to abort the test, it will get caught and buried with not much more than a slight whimper in the log. In this case, the test will carry forth to the next step, which will probably not work, either. I’ve seen projects with this sort of exception handling around every single step definition. In modern test frameworks, the framework will catch all exceptions at the highest level, register the test as failed, and move on safely to the next test. There is no need to catch any exception, unless the test can be recovered.

Changing Steps Without Testing Affected Scenarios

Sharing steps is a wonderful thing, but changing steps without testing all scenarios that use them is a terrible thing. I’ve seen people change step text or step def code and test only their new scenarios. Meanwhile, in the continuous integration environment, a dozen other tests using those steps started failing. (Hell, I’ve seen people push code that doesn’t even compile, but that’s another grievance.)

Multiple Names for the Same Step

Just because you can do something doesn’t mean you should. Different names for the same step may be useful for readability, but please keep the name variants limited.

No Dependency Injection

Dependency injection is the best way to share objects in an automation framework. (Singletons work well, too, but DI allows more careful control of scope.) Many frameworks like Cucumber-JVM even integrate with existing DI frameworks like PicoContainer and Spring. DON’T MAKE NON-CONSTANT VARIABLES GLOBAL! DON’T BLINDLY MAKE THINGS “STATIC” JUST TO SHARE THEM! Globals (or “statics” in Java/C# like languages) are dangerous: they can be easily misused, they are a nightmare to trace, and they can break multithreaded execution. Just use the appropriate design pattern: dependency injection.

The Airing of Grievances: Agile

Agile has essentially replaced the Waterfall model as the “right” software development methodology. It’s a really great process when it’s done right, but people ruin it when they do it wrong. And, oh, how badly it can go wrong. I got a lot of problems with bad Agile practices, and now you’re gonna hear about it!

Breaking the Rules

Agile is a lot like the board game Monopoly. The rules are long and complicated, but they are designed to make the game efficient. However, for some reason, everyone insists on making up their own rules for the game, rather than following the official instructions. For example, players won’t put a property up for auction when they land on it and refuse to buy it, or they will build houses before securing a monopoly. Then, as a result, the game goes on forever and loses its fun. In Agile, every organization seems to want to do things their own special way (as many of these grievances describe), and it almost never goes well when they do. The rules are not meant to be broken, and if they are, there will be consequences.

Going Rogue

Agile is meant to keep people focused on the most important tasks. Much time is spent planning and pivoting to stay on top of priorities. Team members should not deviate from committed work. Don’t go rogue! Don’t work on uncommitted tasks! If something is absolutely pressing, then talk with the scrum master to change the commitments.

Teams that are Too Big

How big is your Agile team? If the answer has more than one digit, then the team is too darn big. The ideal size is 5-9 people because communication becomes too hard with more. Large teams just don’t scale – it’s the law of diminishing returns.

Long Meetings

Nobody wants to be stuck in a long, boring meeting. While there are many Agile ceremonies (planning, grooming, stand-up, review, and retrospective), their meetings are meant to be efficient and productive. Stand-ups should be 15 minutes tops – nobody should ever need to give more than three sentences for their status, and nobody really wants to hear anything longer anyway! People should come prepared for planning and grooming so they don’t literally take all day. Demos should be short and sweet. Keep things moving!

Putting People on More Than One Team

Nobody should be cursed to provide deliverables for more than one Agile team. That’s not fair to the individual, who must spend double-duty in meetings, nor is it fair to the teams, who don’t have a dedicated resource for their work. It applies to every role: developer, tester, product owner, or scrum master. It also burns people out very quickly.

Too Many Top Priorities

I was once part of an Agile team where the product owner issued about a dozen “top priorities.” For. Every. Sprint. Our team had no clue what was really important.

Agonizing Over Story Points

Story points are meant to be sizing estimates for velocity. They don’t need to be perfectly accurate. They shouldn’t track hours. Don’t make big fights over it. Don’t go back and change values. Don’t twist planning poker into a political gambit. PLEASE!

Missing User Story Descriptions

The user story is the primary work artifact. It tells how a new feature should work from the perspective of the user… or, at least it should. If your user story contains just one line (like saying “Build the profile page”), then you just might be doing it wrong. Write user stories in the “As a ___, I want ___, so that ___” format, and provide extra descriptions to help the team understand what the story covers. Non-descriptive stories lead to poorly developed features.

Missing Acceptance Criteria

How do we know when a story is complete? If there’s no acceptance criteria, we don’t! Testers also won’t know what to check. Please write helpful acceptance criteria. A bullet list is fine, and Gherkin would be even better.

Not Including Testing and Automation in the Definition of Done

No. No. No. No. No. No. NO! A story is not complete if it is not tested. It must not be accepted without tests passing and automated. Otherwise, be prepared for an avalanche of technical debt as bugs pile up and the team can’t keep up. The premise of Agile is to deliver small, working features in iterations. Testing must be included! Don’t create separate stories for testing. Don’t push it off to the next sprint. If a team cannot get testing done, then perhaps it should increase story point sizings to include testing and/or commit to less work during a sprint.

Blaming QA for Incomplete Stories

I once heard a developer say bluntly to my automation team, “QA is the bottleneck.” Don’t shoot the messenger! Tests fail because the product under test has problems. Many times, testers don’t even receive builds until very late in the sprint. When stories don’t get done, don’t start a blame game – it’s the whole team’s fault. Try shifting left (perhaps by using BDD) or committing to less work per sprint.

Ignoring Technical Debt

Technical debt is the cost of consequences from poor development decisions. Examples may include: using single-threading when multi-threading is needed, avoiding design patterns, and even building up a test automation framework. Product owners don’t seem to like tech debt tasks because they don’t deliver new features. Unfortunately, tech debt will often cripple a team’s ability to deliver new features – pay now or pay later. Don’t ignore tech debt!

Confusing Agile with “Short Waterfall”

Agile is meant to be a process paradigm shift. It is not meant to be a condensed version of the Waterfall model. Sprints should be short. Responsibilities should be shared. Teams should be self-empowered. Break down silos and become truly Agile!

Using “Agile” and “Lean” Interchangeably

The Lean Startup is a methodology for starting a new business using minimal overhead and reacting quickly to lessons learned. It involves using Agile for product development, but it encompasses so much more than just Agile. Don’t use the terms interchangeably! Get on point with your buzzword bingo game.

Misusing the Term “Continuous Integration”

A nightly build is not CI. A weekly regression run is not CI. Manually-triggered tests are not CI. Manual deployments are not CI. Hand-written test reports are not CI. Don’t lie to yourself – CI is continuous integration, and everything must be automatic.

Forcing Scrum When Kanban May Be Better

Scrum is probably the most widely used Agile process, to the point where most people presume “Agile” means “Scrum.” However, Scrum is not appropriate for all teams. Kanban is a much better process when work items must be done “just in time” – like tech support tickets, build deployments, system maintenance, or emergency recoveries. Good candidates for Kanban are IT help desks and DevOps teams. I’ve used Kanban on automation tools/frameworks teams very successfully. Don’t shoehorn everyone into Scrum.

Hanging Agile Manifesto Posters on the Wall

What are you, Communist?

Complaining about Agile

Complaining doesn’t make it better! Honestly, in my experience, the worst complainers are old-school people who just don’t like change. Then, problems become a self-fulfilling prophecy. Or, they try to break rules and then gripe when things don’t work. If your complaint is about Agile in general, then go take a long, hard look in the mirror. However, if you find a problem in how your team is doing Agile, then bring it up during the retrospective – that’s Agile’s auto-correct mechanism. Complaining for complaint’s sake drags everybody down.

The Airing of Grievances: Selenium WebDriver

Selenium WebDriver is the de facto standard for Web UI automation. It’s a great tool, but like anything good, it can also be misused. And that’s where I have grievances. I got a lot of problems with Selenium WebDriver abuses, and now you’re gonna hear about it!

WebDriver “Unit Tests”

“WebDriver unit tests” are like square circles – definitionally, they are logical fallacies. In my books, a unit test must be white box, meaning it has direct access to the product code. However, Web UI tests using WebDriver are inherently black box tests because they are interacting with an actively running website. Thus, they must be above-unit tests by definition. Don’t call them unit tests!

Making Every Test a Web Test

NO! The Testing Pyramid is vital to a healthy overall testing strategy. Web tests are great because they test a website in the ways a user would interact with it, but they have a significant cost. As compared to lower-level tests, they are more fragile, they require more development resources, and they take much more time to run. Browser differences may also affect testing. Furthermore, problems in lower level components should be caught at those lower levels! Sure, HTTP 400s and 500s will appear at the web app layer, but they would be much faster to find and fix with service layer tests. Different layers of testing mitigate risk at their optimal returns-on-investment.

No WebDriver Cleanup

Every WebDriver instance spawns a new system process for “driving” web browser interactions. When the test automation process completes, the WebDriver process may not necessary terminate with it. It is imperative that test automation quits the WebDriver instance once testing is complete. Make sure cleanup happens even when abortive exceptions occur! Otherwise, zombie WebDriver processes may continue on the test machine, causing any number of problems: locked files and directories, high memory usage, wasted CPU cycles, and blocked network ports. These problems can cripple a system and even break future test runs, especially on shared testing machines (like Jenkins nodes). Please, only you can stop the zombie apocalypse – always quit WebDriver instances!

Using “Close” Instead of “Quit”

Regardless of programming language, the WebDriver class has both “close” and “quit” methods. “Close” will close the current browser tab or window, while “quit” will close all windows and terminate the WebDriver process. Make sure to quit during final cleanup. Doing only a close may result in zombie WebDriver processes. It’s a rookie mistake.

Not Optimizing Setup/Cleanup with Service Calls

Web tests are notoriously slow. Whenever you can speed them up, do it! Some tests can be optimized by preparing initial state with service calls. For example, let’s say a user visiting a car dealership website needs to have favorite cars pre-selected for a comparison page test. Rather than navigating to a bunch of car pages and clicking a “favorite” icon, make a setup routine that calls a service to select favorites. Not all tests can do this sort of optimization, but definitely do it for those that can!

Web Elements with No ID

Developers, we need to talk – give every significant element a unique ID. PLEASE! WebDriver calls are so much easier to write and so much more robust to run when locator queries can use IDs instead of CSS selectors or XPaths. Let’s pick ID names during our Three Amigos meetings so that I can program the tests while you develop the features. Determining what elements are import should be easy based on our wireframes. You will save us automators so much time and frustration, since we won’t need to dig through HTML and wonder why our XPaths don’t work.

Changing Web Elements Without Warning

Hey, another thing, developers – don’t change the web page structure without telling us! WebDriver locator queries will break if you change the web elements. Even a seemingly innocuous change could wipe out hundreds of tests. Automation effort is non-trivial. Changes must be planned and sized with automation considerations in mind.

Not Using the Page Object Model

The Page Object Model is a widely-used design pattern for modeling a web page (or components on a web page) as an object in terms of its web elements and user interactions with it. It abstracts Web UI interactions into a common layer that can be reused by many different tests. (The Screenplay pattern, also good, is an evolution of the Page Object Model; tutorial here.) Not using the Page Object Model is Selenium suicide. It will result in rampant code duplication.

Demonizing XPath

XPaths have long been criticized for being slower than CSS selectors. That claim is outdated baloney. In many cases, XPaths outperform CSS selectors – see here, here, and here. Another common complaint is that XPath syntax is more complicated than CSS selector syntax. Honestly, I think they’re about the same in terms of learning curve. XPaths are also more powerful that CSS selectors because they can uniquely pinpoint any element on the page.

Inefficient Web Element Access

Web element IDs make access extremely efficient. However, when IDs are not provided, other locator query types are needed. It is always better to use locator queries to pinpoint elements, rather than to get a list of elements (or even a parent/child chain) to traverse using programming code. For example, I often see code reviews in which an XPath returns a list of results with text labels, and then the programming code (C# or Java or whatever) has a for loop that iterates over each element in the list and exits when the element with the desired label is found. Just add “[text()=’desired text’]” or “[contains(text(), ‘desired text’)]” to the XPath! Use locator queries for all they’re worth.

Interacting with Web Elements Before the Page is Ready

Web UI test automation is inherently full of race conditions. Make sure the elements are ready before calling them, or else face a bunch of “element not found” exceptions. Use WebDriver waits for efficient waiting. Do not use hard sleeps (like Java’s Thread.sleep).

Untuned Timeouts

WebDriver calls need timeouts, or else they could hang forever if there is a problem. (Check online docs for default timeout values.) Timeout value ought to be tuned appropriately for different test environments and different websites. Timeouts that are too short will unnecessarily abort tests, while timeouts that are too long will lengthen precious test runtime.