In this post, I will show you some advanced usage patterns for working with Playwright in order to take a screenshot of a specific element and modify the contents of the image, either before taking the screenshot or after, using image preprocessing tools.
For web automation/testing, Selenium has been the de facto “standard” since forever. It’s simple to get started with and supports almost every programming language.
I know a lot of people who use Selenium, but I don’t know a lot of people who enjoy using Selenium. (That’s no knock on the Selenium team. They solved a hard problem for lots of devs over the course of many years. Huge impact!) Playwright on the other hand…
I practice “weak TDD”, which just means “writing tests before code, in short feedback cycles”. This is sometimes derogatively referred to as “test-first”. Strong TDD follows a much stricter “red-green-refactor” cycle…
Turns out I also practice “weak TDD” most of the time, but I didn’t know there was a (derogatory) term for it. In this post, Hillel lays out why he does weak TDD and why he doesn’t do strong TDD. Oh, and stick around to the end to learn why he thinks TDD hasn’t conquered the world…
While most teams I talk to would love to be able to run A/B tests to accurately assess the performance impact of certain changes, the problem is pretty much every popular A/B testing tool on the market has such a negative impact on load performance that they’re essentially unusable for this purpose.
If you’re just trying to determine which of two marketing headlines converts better, then perhaps this performance difference isn’t so bad. But if you’re wanting to run an A/B test to determine whether inlining your CSS in the
<head>of your pages will improve your FCP, well, those popular A/B testing tools are just not going to cut it.
He goes on to describe his process for running performant A/B tests on his static site using Cloudflare workers to swap in/out his experiments.
Christopher Meiklejohn has been working for two years on developing an automated resilience testing tool called Filibuster and was able to test it out at DoorDash during his research internship:
Access to DoorDash’s real-world industrial microservice application was extremely valuable both to ensure that Filibuster’s design matches how microservice applications are developed today and to influence future features that I would not have identified in a lab setting.
The results were pretty good! Maybe we won’t need chaos monkeys as tools like Filibuster advance?
In short, Filibuster can identify many of the technical resilience issues that exist in applications earlier, at the time of development, without testing in production as required in more traditional chaos engineering techniques.
Victor Engmark thinks we should start test names with “should” for a handful of reasons, here’s a few:
- It removes redundancy, because the function name should already be in the call stack.
- It is falsifiable, a person reviewing the test can decide to which degree the name agrees with the actual test.
- It encourages testing one property of the function per test
I don’t disagree, but I like to take it a step further: Let the “should” be implied by the rest of the test name.
should replace children when updating instance
replaces children when updating instances
should apply discount when total cost exceeds 100 dollars
applies discount when total cost exceeds 100 dollars
Most of Victor’s reasons for using “should” still apply with this format, but it’s less verbose and more accurately describes the software working as expected when the tests pass.
Good for them (and us)! But what does that mean in practice?
Over the next few months, we’ll be completing the OpenJS Foundation’s incubation program checklist, including transferring the Jest domain, repo, website, and other assets to OpenJS. We’ll also be updating the code of conduct and contributor license agreement.
Additionally, as part of this move, we will be publishing a project charter and creating new governance policies that will document the process for gaining commit access, as well as our leadership selection process.
Next up: React?! A guy can dream…
I love articles like this one because I was ready to disagree with it going in, but it was so well-reasoned and articulate that I ended up agreeing with most everything the author proposes.
This hit my radar a few times in the past year – this week, and then most recently a few months back when we had Richard Hipp on The Changelog (again) – but, I didn’t post it to the newsfeed.
Here’s what’s interesting about the SQLite test suite – it’s their secret sauce…the sustaining enablement of building a support business around SQLite. Here’s a direct quote from Richard Hipp in that episode.
Originally we thought we were gonna sell this and make money from it, and that’s how we were gonna support ongoing development. That didn’t really play out, nobody ever bought it. It does sort of become our business value, our intellectual property. I mean, you can take the SQLite code and fork it and start your own thing…but you don’t have the full test suite. You’ve got a lot of tests, but not all of them. So we’ve got a little bit of advantage over you there.
Click here to play that episode from this quote.
Jacob Kaplan-Moss, who has been writing a lot about good interview questions and how to hire well:
Work sample tests are an exercise, a simulation, a small slice of real day-to-day work that we ask candidates to perform. They’re practical, hands-on, and very close or even identical to actual tasks the person would perform if hired. They’re also small, constrained, and simplified enough to be fair to include in a job selection process.
To give you a more concrete idea of what I’m talking about, here are several examples of work sample tests I’ve used…
And just in case you think he’s prescribing whiteboarding…
However, work sample tests are also a minefield: the space is littered with silly practices like whiteboarding, FizzBuzz, Leetcode, and “reverse a linked list”-style bullshit. The point of this series is to separate these silly practices from the good ones and to give you a framework and several examples to use in your hiring rounds.
Property-based tests give us more confidence in our code. They’re great at catching edge-cases we may not have thought of otherwise. But this confidence comes at a cost. Property tests take more effort to write. They force you to think hard about what the code is doing, and what its expected behaviour should be. It’s hard work. And on top of that, running 100+ tests is always going to take longer than running 3–5 example-based tests. This cost is real, and it raises the question:
How do we keep ourselves from over-specifying or writing unnecessary tests?
Property-based testing helps us write better tests, with less code, and greater coverage. This leads to more confidence in our code, and fewer bugs in our applications. But, as always, there’s a price. Property tests take more effort to write, and they take longer to run. But they’re worth it.
Recently I discovered additional reasons to write tests for my code! Besides obvious and well-known ones described in books and many blog posts, I realized that the process of writing tests has also psychological effects for me. These effects are especially helpful in cases of hotfixes that need to be deployed as soon as possible.
The top 1% of companies spend thousands of hours building their own A/B testing platforms in-house. The other 99% are left paying for expensive 3rd party SaaS tools or hacking together unmaintained open source libraries.
Growth Book gives you the flexibility and power of a fully-featured in-house A/B testing platform without needing to build it yourself.
On 24th April 2021, Angular announced the deprecation of their E2E testing tool protractor. It was unclear if there will be a successor or if Angular delegates this to its users. In this article, I will provide a short overview over the differences between the various E2E frameworks, and argue why you should use Cypress.
I’ve heard nothing but high praise of Cypress and thoroughly enjoyed our conversation with Gleb Bahmutov when he joined us on JS Party.
In this article, I’d like to explore a couple of implementations of sorting algorithms. However, I’d like to do so driven by unit tests. The examples are written in Go, but don’t worry if you never worked with Go before. The emphasis here is on the journey and the joy of building solutions guided by tests!
We first talked fuzzing with Katie Hockman back in August of 2020. Fast-forward 10 months and native fuzzing in Go is ready for beta testing! Here’s Katie explaining fuzzing, for the uninitiated:
Fuzzing is a type of automated testing which continuously manipulates inputs to a program to find issues such as panics or bugs. These semi-random data mutations can discover new code coverage that existing unit tests may miss, and uncover edge case bugs which would otherwise go unnoticed. Since fuzzing can reach these edge cases, fuzz testing is particularly valuable for finding security exploits and vulnerabilities.
It looks like the feature won’t be landing in Go 1.17, but they’re planning on it sometime after that. Either way, you can use fuzzing today on its development branch.
“The tests are timing out again!”, someone yells. “Alright I’ll bump them”, you instinctively respond. Then you pause and feel uneasy. Is there another way?
In this blog post, I share my growing disconnect with code-coverage and unit-testing. I then detail the method I’ve been using for the greater part of 7 years and how it still allows me to preach at length that being correct is the single most important thing for a developer.
Here’s a pretty useful idea for library authors and their users: there are better ways to test your code!
I give three examples of how user projects can be self-tested without actually writing any real test cases by the end-user. One is hypothetical about
django and two examples are real and working: featuring
dry-python/returns. A brief example with
import deal @deal.pre(lambda a, b: a >= 0 and b >= 0) @deal.raises(ZeroDivisionError) # this function can raise if `b=0`, it is ok def div(a: int, b: int) -> float: if a > 50: # Custom, in real life this would be a bug in our logic: raise Exception('Oh no! Bug happened!') return a / b
This bug can be automatically found by writing a single line of test code:
test_div = deal.cases(div). As easy as it gets! From this article you will learn:
- How to use property-based testing on the next level
- How a simple decorator
@deal.pre(lambda a, b: a >= 0 and b >= 0)can help you to generate hundreds of test cases with almost no effort
- What “Monad laws as values” is all about and how
dry-python/returnshelps its users to build their own monads
I really like this idea! And I would appreciate your feedback on it.
Alabe Duarte shares his personal exposure with TDD over the years. This includes:
- why he believes TDD is important
- the subjectiveness of “good design”
- when doing TDD doesn’t help
Devon C. Estes:
It’s fairly common for folks who haven’t used mutation testing before to not immediately see the value in the practice. Mutation testing is, after all, still a fairly niche and under-used tool in the average software development team’s toolbox. So today I’m going to show a few specific types of very common problems that mutation testing is great at finding for us, and that are hard or impossible to find with other methods
He goes on to detail the “multiple execution paths on a single line” problem, the “untested side effect” problem, and the “missing pin” problem.
Typically, people say that testing is like a pyramid. A wide base of unit tests and very few end-to-end tests. I believe we’ve come to a point where a crab strategy is a better approach.
Headless recorder is a Chrome extension that records your browser interactions and generates a Puppeteer or Playwright script. Install it from the Chrome Webstore. Don’t forget to check out our sister project theheadless.dev, the open source knowledge base for Puppeteer and Playwright.
You may have heard of this when it was called Puppeteer Recorder, but its recent addition of Playwright support warranted a rename.