Web UI tests with Selenium WebDriver must interact with elements on a Web page. Locating elements can be tricky because expected elements may or may not be on the page. Furthermore, WebDriver might not be able to interact with some elements that exist on the page. That may seem crazy, but let’s understand why.
Web UI interactions universally follow these steps:
Wait for an element to be ready.
Get the element using a locator (ID, CSS selector, XPath, etc.).
Send commands (like clicking or typing) or queries (like getting text) to the element.
Clearly, an element must be “ready” before interactions can happen. As humans, we intuitively define “ready” as, “The page is loaded, and the element is visible.” Automation code is a bit more technical because there are two different ways to define readiness:
Existence: the element exists in the HTML structure of the page.
Appearance: the element exists and it is visible on the page.
Existence can easily be determined by WebDriver’s “find elements” method. The plural “find elements” method will return a list of all elements matching a locator query. If no elements match the locator, then an empty list is returned. The singular “find element” method, on the other hand, will return the first element matching the locator or throw an exception if no elements are found. Thus, the plural version is more convenient to use for checking existence.
Here’s an example existence method in C#:
public bool Exists(IWebDriver driver, By locator) =>
driver.FindElements(locator).Count > 0;
Checking for existence is the most basic level of readiness. If an element doesn’t exist, interactions with it simply cannot happen. However, existence alone may not be sufficient for interactions. Selenium WebDriver requires elements to not only exist but also to be displayed for interactions like sending clicks and scraping text. Existing elements may be scrolled out of view or even deliberately hidden. WebDriver calls to such elements will yield cryptic exceptions. That’s why waiting for appearance is usually the better readiness condition.
Here’s an example appearance method in C#:
// Assume that the locator targets one element, not multiple
public bool Appears(IWebDriver driver, By locator) =>
Exists(driver, locator) && driver.FindElement(locator).Displayed;
Existence must be checked first, or else the “Displayed” call will throw an exception whenever existence is false.
Putting it all together, here’s what a button click interaction could look like in C#:
// Assume this is a method in a Page Object class
// Assume that "Driver" is the WebDriver instance
public void ClickThatButton()
var button = By.Id("that-button");
var wait = new WebDriverWait(Driver, new System.Timespan(0, 0, 15));
wait.Until((driver) => Appears(driver, button));
It’s good practice to make explicit waits before locating and using elements. It’s also good practice to get fresh elements for every interaction call in order to avoid pesky stale element exceptions. Calls like these should be placed in Page Object methods or Screenplay Pattern tasks and questions so that interactions are safe and thorough.
Appearance may not always be the right choice. There may be times when a test should check if an element doesn’t exist or if an element exists but is hidden. Just think before you code.
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.
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.
When I was a kid, I was an enthusiastic Boy Scout. And every year, I looked forward to summer camp. For one full week, I would have a mini-adventure in the woods with my friends while earning new ranks and developing new skills. Summer camp was the highlight of every summer. As an adult, this is exactly how I feel about PyCon.
PyCon 2019 was my second time at PyCon. While I doubt any conference will ever have the same impact on me as my first PyCon, my second one was nevertheless every bit as good. I had a phenomenal experience. As always, I like to capture my reflections in an article so that I never forget the wonderful times I had. Here’s my story.
PyCon 2018 was a career-changing experience for me. I felt it at the time, and I can validate it now a year later. PyCon 2018 was my first serious engagement with the Python community. PyCon 2018 inspired me to speak at other conferences. PyCon 2018 introduced me to friends I still have today. As soon as PyCon 2018 ended, I knew that I needed to return for PyCon 2019.
Between 2018 and 2019, PrecisionLender (my employer) started doing much more Python work, especially in our data analytics division. I got approval from my manager to go to PyCon, but I also knew that others in the data division would benefit from PyCon as well. When I suggested the idea to the VP, he replied with one line: “Let’s do this thing!” With his blessing, I convinced four other PrecisionLender-ers to join me: Adam, Henry, Joe, and Raff.
I’m so thankful PrecisionLender approved our trips. Going with other friends from my company boosted not only my excitement for the conference but also my desire to learn new things. I’m proud to represent a company that supports its employees so well.
Good conferences are good but exhausting. They cram hundreds of adrenalized people into back-to-back activities requiring deep focus for hours at a time and for consecutive days. Amidst the mania, it is crucial to pace oneself. My friend Kojo sums this up perfectly in what he calls the “self care sprint.” It’s okay to step back to catch your breath. It’s vital to one’s mental health to take breaks, rest, and recover, especially at conferences as intense as PyCon.
Heeding Kojo’s advice, I took a #SelfCareSprint on the day before PyCon tutorials began. How so? I spent my afternoon at the Cleveland Museum of Art, which exhibits pieces from around the world dating from ancient times through the present day. Make no mistake: the Cleveland Museum of Art is world-class. In addition to their permanent collections, they had a special exhibit on Shinto artifacts from Japan. I barely had enough time to walk through all the galleries. What I did see impressed me, inspired me, and challenged me. Some pieces even spoke deeply to my soul.
The dichotomy of art and technology balance each other. Exploring pieces of art and the viewpoints they represent helped me center myself. I could clear my mind in preparation for the conference. I gained rest and recovery. I am human, after all.
PyCon 2019 hosted two days of tutorials before the main conference. Whereas talks are thirty minutes long and open to anyone, tutorials are three-hour sessions that require preregistration for limited seats. Tutorials are meant for hand-on learning with expert instructors. I had never attended tutorials at a conference before, and so this time, I wanted to try.
My first tutorial was Writing About Python (Even When You Hate Writing) by Thursday Bram. Since I do lots of blogging (and I ultimately want to write a book), I wanted to get first-hand advice on technical writing in the Python ecosystem. Thursday gave great advice on writing techniques and gotchas. The most valuable takeaway was her proofreading checklist. Her tutorial also inspired me to do something cool later in the conference. (Keep reading!)
My second tutorial was To trust or test? Automated testing of scientific projects with pytest. Unfortunately, this tutorial wasn’t right for me. I thought it would be about testing within data science, but it turned out to be a basic walkthrough of pytest. I didn’t learn any new material. What I did learn, though, was that I should be pickier with tutorials – I had to pay in advance, and I couldn’t just walk out to another talk.
My third tutorial was Escape from auto-manual testing with Hypothesis! by Zac Hatfield-Dodds. Hypothesis, a property-based testing tool, is hot right now. I first learned about it at the previous year’s PyCon, and I always wanted to learn more. Zac provided not only helpful lectures but a rigorous set of examples for us to complete. Hypothesis also works seamlessly with pytest. Zac made be a believer: Hypothesis is awesome! I need to spend more time learning it on my own.
As always, the talks were on point. I didn’t attend as many talks this year because I was too busy in the “hallway track,” but there were quite a few noteworthy ones that I attended.
In Don’t be a robot, build the bot, Mariatta showed how she and the Python core developers automated their GitHub workflow with the help of useful bots. It was cool to see how mundane processes can be automated away and how much more efficient teams can become.
In Break the Cycle: Three excellent Python tools to automate repetitive tasks, Thea Flowers showed how to use tox, nox, and Invoke to automate just about anything in Python. I’ll definitely refer back to this talk for testing.
In ¡Escuincla babosa!: Creating a telenovela script in three Python deep learning frameworks, Lorena Mesa showed us how serious machine learning can also be used for fun projects. Although the telenovela script she generated was short and humorous, it clearly proved that ML can get the job done.
In Scraping a Million Pokemon Battles: Distributed Systems By Example, Duy Nguyen showed how he scraped data from competitive Pokémon battles to level the playing field for new players. In the process, he developed a pretty slick distributed systems setup!
In Shipping your first Python package and automating future publishing, Chris Wilcox showed best practices on building and releasing Python packages. This talk was well-timed for me – I’ll definitely use this info for a current pet project of mine.
Dependency hell: a library author’s guide by Yanhui Li and Brian Quinlan will also be a great resource when considering dependencies for packages.
In to GIL or not to GIL: the Future of Multi-Core (C)Python, Eric Snow showed his thoughts for how to fix problems with the GIL and true multi-core processing.
In The Perils of Inheritance: Why We Should Prefer Composition, Ariel Ortiz made clear the nasty side effects inheritance can have and how composition is often a much better approach. The talk was fairly introductory, but I couldn’t agree more.
The expo hall was full of companies and organizations. The swankiest booths this year were:
Capital One – the Guido portrait and puzzle and the Zen of Python wall
Jetbrains – content developer tables for PyBites, Real Python, and others
Microsoft – four interactive Azure stations + active lab tables
However, my favorite company in the expo hall, hands down, was The Pokémon Company International. Their table was small and easily overlooked, but every time I passed by, it was packed. Everyone loves Pokémon! I got to meet a few of their engineers and managers. Apparently, they do much of their backend in Python. They’re also growing quite a lot. They were raffling off a giant Pikachu, and one of the engineers even developed a Google Home app that would make Pikachu respond whenever someone spoke to it! It was so charming to see them there. I’m glad that things are going well for Pokémon.
If you don’t overfill your swag bag, then you’re doing PyCon wrong. This year’s haul was as good as last year’s. I walked away with:
A deck of cards with the Zen of Python from Capital One
An artistic deck of playing cards from Heroku
16 packs of Pokémon cards
A JetBrains yo-yo
A few pairs of sunglasses
Water bottles from DoorDash, Wayfair, and Citadel
A guide to building Slack apps
The best t-shirt award goes to Microsoft for their Visual Studio Code shirt, with honorable mentions for LinkedIn and SmartBear. I also shared a good amount of this swag with my coworkers at PrecisionLender.
Cleveland (and greater Ohio) are renowned for craft breweries. Every time I return to Ohio, I’m always delighted by the beers I discover. I spent many lunches and dinners with a flight set on the side. Here’s where I went:
Hofbräuhaus Cleveland, twice! (I even bought the souvenir Maßkrug!)
Masthead Brewing Company
Noble Beast Brewing Company
Southern Tier Brewing Company
Great Lakes Brewing Company
The best was the Lichtenhainer from Noble Beast – a sour that tasted like a ham sandwich on sourdough. The worst was the “shampoo beer” from Southern Tier – did they forget to rinse the lines after cleaning them?
Back at PyCon 2018, I met an Aussie by the name of Julian Sequeira, co-founder of PyBites. We hit it off. In fact, meeting Julian is one of the reasons why I continue to engage the Python community today. Through Julian, I met other friends like Jason Wattier, Brian Okken, Cristian Medina, and many others. Leading up to PyCon 2019, Julian organized a BIG dinner at Great Lakes Brewing Company for a bunch of Python content developers: PyBites, Real Python, Python Bytes, Test & Code, tryexceptpass, and Automation Panda (me!). Not only was it a time of sweet reunion, but I finally got to meet others like Bob Belderbos, Michael Kennedy, and David Amos in person. One of the best parts of the dinner was when a few of us chose to walk back to the hotels over the bridge instead of calling taxis. The night was cold, but the experience was worth every second.
Sadly, I did not get to deliver a full talk or tutorial at PyCon 2019. Believe me, I submitted. But that didn’t stop me from trying – there’s always one more chance with lightning talks! One exercise during the Writing About Python tutorial was to pitch a lightning talk idea. At the time, I struggled to come up with a good topic. I first considered something about testing or being a tester, but those ideas just didn’t feel right. Then, I struck gold: what about giving helpful tips for blogging, based on my experiences with Automation Panda?
I put my idea on the call-for-lightning-talk-proposals on Saturday morning: “3 Quick Tips for Software Blogging.” When I didn’t receive any notification by lunchtime, I thought my pitch had been rejected. Then, while chilling in the quiet room at 3pm, I received an email: “Congrats! You’re giving your lightning talk today at 5pm!” Excitement, then panic, took over. I threw some slides together, rehearsed them in my head, and marched myself to the main auditorium. My lightning talk was second in queue, and I delivered it like a BOSS!
Ever since my first PyCon, I’ve dreamed about having a Python conference in the Carolinas. There was a PyCarolinas 2012 and a PyData Carolinas 2016, but both were one-hit wonders. My dream remained in my back pocket until PyCon 2019.
While meandering the expo hall on Friday, I ran into Tim Hopper and Brian Corbin, two friends who were also from the Carolinas. We talked about lots of things, but one point of discussion was about relaunching PyCarolinas. Later, Dustin Ingram, chair of PyTexas, tweeted that there would be a conference organizer’s open space on Saturday. I asked if I could join because of my PyCarolinas dreams, and he said absolutely yes. Brian and I both attended, made connections, and got tons of helpful information.
Dustin then asked me if I’d like to include a slide for PyCarolinas in the “regional conference parade” on Sunday morning after the lightning talks. Heck yeah! PyCarolinas was the very last slide as a call-to-action: We have a dream; come help us make it real!
At 10am on Sunday, I held an open space to talk about (re)launching PyCarolinas. 26 people came! We got everyone’s info, created a Slack room, and started throwing around ideas. In the week after the conference, over a hundred people signed up for our Slack room. The excitement is palpable. Our goal is to host PyCarolinas in summer of 2020 for 150+ people. I’m so thankful I got the opportunity to be the spark that lit this wildfire, on such a big stage.
Together with my blog, I use my Twitter handle @AutomationPanda for professional development. Twitter is especially helpful during conferences for communicating with friends and sharing experiences. During PyCon 2019, I crossed a big milestone: I hit over 1000 followers! That was cool.
I also made my first viral tweet, thanks to a sticker from Facebook:
If you read these reflections down this far, thank you. Seriously, I mean it.
The best part about PyCon 2019 for me was the time I spent with my friends.
PyCon 2019 was a high point for friendships. Everyone I knew was there. I couldn’t walk for 10 minutes around the convention center without running into someone I knew. I feel like I’m truly part of the Python community now. Here were just a few highlights:
Going there with my PL team: Adam, Henry, Joe, and Raff.
German dinner and souvenir Maßkrugs with Adam at Hofbräuhaus.
“Shampoo” beer with Joe and Adam at Southern Tier.
Snagging Pokémon cards on opening night with Mason Egger, and then running into Jason Wattier on the way.
Ramen dinner and Hilton rooftop drinks with the PL crew plus Mason.
Impromptu lunch with Adrienne so she could share the awesome things she’s accomplishing.
PyCon Canada 2018 was my fourth and final Python conference of 2018. I proposed a talk on a whim after seeing the CFP on Twitter. What the heck, why not? It couldn’t hurt to try. Much to my surprise (and delight), I was accepted to speak! So, up to the Great White North I went for the first time since childhood.
#PyConCA2018 took place in Toronto, Ontario from November 10-13 at the Chestnut Residence downtown. I attended the conference (Nov 10-11) but skipped out on the sprints (Nov 12-13). It looked like about 400-500 people attended the conference, but I don’t know the exact count. A few vendors had tables with swag, but the talks were clearly the main focus of the conference.
PyConCA offered three tracks for talks plus a tutorials track. There were two time slot lengths for talks: 10 minutes and 30 minutes. I had not attended a conference with short 10-minute talks before, but they turned out to be a great way to cover a broader range of topics in a short amount of time. The tutorials were long-running sessions for which anyone could register at no additional charge, but they each had a limited number of seats. (I regret not signing up in advance for the Kubernetes tutorial.) There were also four decent keynote addresses.
I spent a lot of time reworking the slides, writing new example code, and rehearsing my words before the talk. And I felt great when I presented it: without any script, I hit all the major points without skipping a beat and ended right on time. I felt my passion flow through me as I spoke. This tweet pretty much summed up my feelings:
Meeting people is one of my favorite parts of Python conferences. Everyone is friendly. Everyone will chat with you. Everyone will get excited about whatever makes you excited. This time around, I ended up in a posse with a few other guys who mostly attended the same talks and also sat at the same lunch table. I hope our paths cross again. I also got to meet Elaine Wong, the conference chair.
After the Conference
I was on my own for both evenings after the conference talks. My Airbnb rental was just two blocks away in Chinatown, so I could walk to and from the conference center (in the bitter Toronto cold). On Saturday night, I ate a delicious dry hotpot of beef, lotus flowers, and wood ear mushrooms at the House of Gourmet, followed by a fancy bubble tea in a light-bulb-shaped glass across the street at Royaltea. On Sunday night, I treated myself to foot-and-body massage at Evergreen Beauty and Wellness. My therapist, who was from Beijing, helped me practice my Mandarin. Thereafter, I went to Sichuanren for an all-you-can-eat hotpot buffet: beef, pork, lamb, seafood, and veggies. It’s so much fun to visit a big city with a large Chinatown – it provides access to things I can’t always get at home. That US-to-Canadian-dollar exchange rate is quite favorable, too. The only challenges I faced were (a) no mobile phone service and (b) worrying if establishments would accept my credit/debit cards. The temps also hovered around freezing.
PyConCA was a strong finish for my 2018 conferences. I’m so thankful for my opportunity to speak, and I’m glad that I took the time to attend.
My favorite physical takeaway items of swag were:
My PyConCA sticker, now proudly displayed on my Macbook
My PyConCA t-shirt, which will soon appear in my rotation
My PyConCA “toque” (Canadian word for “knit winter cap with a pom-pom on top”)
My main inspirational takeaway from this conference could be summed up in one word: confidence. I feel much more confident in myself as a conference speaker after nailing my talk this fourth time. After listening to a number of talks, I also feel much more confident in my Python web development skills. Picking up Flask (which is on my todo list) should be doable. Finally, I feel capable of learning data science and AI with Python when the time comes. Many talks showed how machine learning can solve novel problems with straightforward tools and techniques.
That should conclude this panda’s round of conferences for the year. I look forward to what 2019 brings!
PyTexas 2019 was an incredible Python conference. It was held at the Central Library in Austin, Texas from April 13-14. I’m so glad I went. Even though this was my seventh Python conference, it was one of my favorites so far. Here’s a brief recap of my experiences.
Why I Went
I consider myself very fortunate to have been able to go to PyTexas 2019. After my talk proposals for PyCon 2019 were rejected, I saw this tweet from Dustin Ingram, the conference chair for PyTexas:
Thankfully, my talk was the very second talk of the conference. I could get it out of the way early so I could enjoy the rest of the conference without the nerves. And everyone always loves the pandas.
I also gave a Lightning Talk for the first time! I talked about the difference between unittest and pytest. My talk starts at 30:17, but be sure to listen to all of the talks.
I’d also like to thank my employer, PrecisionLender, for sponsoring my trip and enabling me to speak.
Talks are usually the main part of any conference. PyTexas 2019 was a single-track conference, meaning that everyone saw all of the talks. All talks were memorable for me, but I’ll write a separate post about the talks once all the recordings are posted. Here, I’ll cover other awesome things that happened.
My Recovery Day
Things had been very stressful for me in the first few months of 2019. I came to PyTexas essentially exhausted from life, and I needed a “Self Care Sprint” (as Kojo would say). So, that’s exactly what I did: I flew into Austin on Friday morning and spent the whole afternoon just being a low-key tourist. I ate a Texas-sized lunch at Stubb’s BBQ, viewed the artwork at Mexic-Arte Museum, walked along the Colorado River, and nearly fell asleep in the Central Library after perusing the stacks. That evening, I met up with other speakers at the Spider House for an informal pre-conference get-together. Even though I wasn’t “productive” by any professional definition, I felt thoroughly refreshed and ready for the excitement to come.
Austin has been invaded by electric scooters. They are on every street corner. There must be half a dozen different brands. Even Uber and Lyft have scooters for rent! Instead of hailing ride shares downtown, I just hopped the nearest Lime scooter. They go really fast, and they’re tons of fun!
The First After-Party
Literati Books generously hosted an after-party at Jo’s Coffee after the first day of the conference. I got to spend time with a bunch of cool people from the conference while enjoying sliders and craft beer. Carl even shared some of his jerky with us!
Other Testing Talks
I always get a rise out of testing talks at conferences. Python conferences always have a few but only a few. PyTexas had three. I think Kojo‘s tweets summed up my enthusiasm perfectly:
The Zen of Python Teams
Adrienne delivered one of the best keynote addresses I’ve ever attended. Seriously, go watch it. She talked about how the Zen of Python can be applied not only to code but also to teams. The best part was the “Easter egg” at the end. The Zen of Python famously leaves the 20th line blank so that we can make it for ourselves. Adrienne challenged us to come up with our own 20th point after handing out real Easter eggs to everyone in the audience! Mine? People matter.
I had never eaten at Whataburger before. This trip, that changed. William, Brian, and I hopped on those electric scooters and went to the Whataburger across the river for lunch on day 2. The patty melt was tasty, but the Dr. Pepper milkshake was out of this world! The views from the bridge were gorgeous as well.
The Second After-Party
After the conference ended, William, Aly, and I went to Mort Subite, a cool Belgian beer bar, to celebrate and unwind. Then, we rode electric scooters over to Baton Creole for a late-night dinner with Adrienne. We had some good food and even better discussions. It was the best way to end PyTexas!
PyTexas was the first conference where I felt like I fully belonged from day one. Every previous conference was a bit of a shot in the dark for me because I was still new to the Python community. PyTexas 2019 felt almost like a reunion. I strengthened existing friendships and made new ones: Adrienne, Kojo, Dustin, Ernest, Aly, William, Piper, Andy, Carl, Mason, Michael, Brian, and so many more. I also felt like I made a bigger impact at PyTexas than at other conferences because I genuinely felt like part of the community.
We should never take conferences (or any moments) for granted. Truly wonderful things happened at PyTexas. I felt creative. I felt inspired. I felt challenged by new ideas. I felt the itch to try new things. I left on a post-conference high and, surprisingly, I wasn’t particularly tired. The organizers did a phenomenal job running the conference smoothly and successfully. Seriously, hats off to them – many thanks for a job well done. As attendees, we should be grateful for all the hard work so many people did for the conference, and we should capitalize on what we take away from the conference.
Single-track and multi-track yield two very different conference experiences. PyTexas 2019 was my second single-track conference and my first one for a Python conference. Overall, I think the single-track format worked very well. Putting everyone on the same track in the same room builds a strong sense of camaraderie. It also gives speakers a much more prominent platform. However, multi-track provides more choices for attendees, and it gives more people the opportunity to speak. Both are good. I think it would be cool if future conferences do both: maybe one day for single-track and another day for multi-track.
I’m going to (attempt to) develop a new Python package. For a while, I’ve wanted to implement a particular testing pattern in a Pythonic way. My goal is to develop and release it to PyPI as an open-source package. I never had the time or clarity to do it until now. PyTexas gave me a huge boost, and I hope I can carry my vision through to delivery!
People matter. The Python community is a truly wonderful group. People come for the language and stay for the community – it’s true. PyTexas 2019 has challenged me to be a better person and to help people through software.
Test automation is the cornerstone for continuous software delivery pipelines. Automation repeatedly hits new features with a barrage of tests that could never be completed manually in time. From my experiences, though, test automation code can be some of the worst code in the software industry. Teams frequently overlook its importance, its workload size, and its unique technical challenges. The resulting code can become a heapin’ mess! You might even call it “bankrupt.”
In this situation, should a team give up on their current test automation solution and just start over from scratch? Maybe, but maybe not. Don’t be quick to nuke everything and start over! No project is perfect, and some can be recovered. Starting a whole new test automation solution is not a light decision.
Here are a few problems that should be addressed within the existing test automation solution instead of starting over:
Tests don’t add value? That’s easy to fix: just remove the low-value tests. The framework is separate from the test cases.
Tests are flaky? Find the root cause. Typically, flaky tests can be fixed with small updated to the test case or to an aspect of the framework. If the feature under test itself is flaky, then fix the feature or consider testing it manually instead of with automation.
The original authors are gone? Figure out their code before writing your own. Their code might be good once you understand it.
The team uses poor practices? Fix the practices before fixing the code. Otherwise, the new code won’t be any better than the old code.
Signs to Consider
Nevertheless, there are times when a team should start over. Look for these signs, and proceed thoughtfully.
The test frameworks and packages are deprecated. Although the tests may run today, they may not run tomorrow. Finding others to work on it will be difficult, too. For example, nose was once the Python framework of choice, but now it’s dead. Pick a more modern framework. Hopefully, parts of the old tests can be salvaged.
Test case independence is systemically violated. Each test case must be independent. It should not depend upon the outputs of any other tests. It should not interrupt any other tests. The litmus tests for independence is that tests should be able to run successfully in any random order. Interdependent tests are not scalable, difficult for reruns, and potentially dangerous. The only way to fix them is to completely rewrite them.
There is no separation between unit tests and feature tests. White-box unit tests cover code, whereas black-box feature tests cover live features. They occupy different Testing Pyramid layers and should happen at different stages in a CI/CD pipeline. An automation solution with no separation between these types of tests reveals a lack of planning and strategy, and continuous testing will be much tougher to achieve.
The framework lacks cohesive architecture, designs, and patterns. Good solutions are designed, not hacked. Designs scale. Hacks don’t. Building new tests on a shaky platform will yield shaky tests.
Critical fixes would require a majority of tests to be rewritten. Some issues are pervasive, especially when code is repeatedly duplicated. If framework problems are so widespread that tests would need to be rewritten anyway, then it might be easier to start fresh with a new solution.
The Nuclear Option
If you feel like you really do need to start a new test automation solution from scratch, make sure to do it right. You won’t want to redo everything again in a few years! Here’s some advice:
Define your goals. What problems do you want to solve? How can testing and automation help? What can you reasonably achieve? Are you willing to make necessary changes to achieve these goals?
Treat test automation as a project. Test automation is software and requires the same rules and practices. It takes time and expertise. Make sure to allocate time, money, and resources to its development and execution.
Learn how to develop test automation well. It’s not “just writing scripts” – it’s a special domain. Take courses from Test Automation University. Read more Automation Panda articles. Attend webinars and conferences. Seek consulting help if necessary.
Draw a line in the sand between the old and new solutions. Commit to writing all new tests in the new solution. Meanwhile, continue to run tests from the old solution as appropriate – there’s no need to axe its test coverage. Decide if migrating old tests to the new solution is worthwhile for your team. This could also be an opportunity to clean up old tests and cut out low-value areas.
Starting a new test solution is a lot of work, but it can also be rewarding. Good luck!
Sharing steps between feature files can be a bit of a hassle.
pytest-bdd is a plugin for pytest that lets users write tests as Gherkin feature files rather than test functions. Because it integrates with pytest, it can work with any other pytest plugins, such as pytest-html for pretty reports and pytest-xdist for parallel testing. It also uses pytest fixtures for dependency injection.
Step definition modules must have explicit declarations for feature files (via “@scenario” or the “scenarios” function).
Scenario outline steps must be parsed differently.
radish is a BDD framework with a twist: it adds new syntax to the Gherkin language. Language features like scenario loops, scenario preconditions, and constants make radish‘s Gherkin variant more programmatic for test cases.
It lacks the feature richness of the other frameworks.
It doesn’t appear to have much active, ongoing support.
freshen was one of the first BDD test frameworks for Python. It was a plugin for nose. However, both freshen and nose are no longer maintained, and their doc pages explicitly tell readers to use other frameworks.
None of these frameworks are perfect, but some have clear advantages. Overall, my top recommendation is pytest-bdd because it benefits from the strengths of pytest. I believe pytest is one of the best test frameworks in any language because of its conciseness, fixtures, assertions, and plugins. The 2018 Python Developers Survey showed that pytest is, by far, the most popular Python test framework, too. Even though pytest-bdd doesn’t feel as polished as behave, I think some TLC from the open source community could fix that.
Here are other recommendations:
Use behave if you want a robust, clean experience with the largest community.
Use pytest-bdd if you need to integrate with other plugins, already have a bunch of pytest tests, or want to run tests in parallel.
Use radish if you want more programmatic control of testing at the Gherkin layer.