惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
雷峰网
雷峰网
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学
腾讯CDC
T
Tailwind CSS Blog
A
About on SuperTechFans
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
The Cloudflare Blog
D
DataBreaches.Net
Recent Announcements
Recent Announcements
Engineering at Meta
Engineering at Meta
B
Blog
博客园 - 聂微东
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
博客园 - 司徒正美
MongoDB | Blog
MongoDB | Blog
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research

Dropbox Tech Blog

Testing cookie behavior across hundreds of web surfaces with our in-house auditor Improving infrastructure efficiency for growing demand in the age of AI How our universal content processing platform Riviera evolved for AI and beyond How we used DSPy to turn AI evaluations into better responses in Dash chat How Dropbox uses MCP and Dash to close the design-to-code security gap Beyond code generation: rethinking engineering productivity in the age of AI agents Introducing Nova, our internal platform for coding agents Improving storage efficiency in Magic Pocket, our immutable blob store Reducing our monorepo size to improve developer velocity How we optimized Dash's relevance judge with DSPy Using LLMs to amplify human labeling and improve Dash search relevance How low-bit inference enables efficient AI Insights from our executive roundtable on AI and engineering productivity Engineering VP Josh Clemm on how we use knowledge graphs, MCP, and DSPy in Dash Inside the feature store powering real-time AI in Dropbox Dash Building the future: highlights from Dropbox’s 2025 summer intern class Fighting the forces of clock skew when syncing password payloads Introducing Focus, a new open source Gradle plugin Making camera uploads for Android faster and more reliable How Dropbox Replay keeps everyone in sync Why we built a custom Rust library for Capture Detecting memory leaks in Android applications How we sped up Dropbox Android app startup by 30% Why we chose Apache Superset as our data exploration platform Revamping the Android testing pipeline at Dropbox Our counterintuitive fix for Android path normalization JQuery to React: How we rewrote the HelloSign Editor How we ensure credible analytics on Dropbox mobile apps Engineering Dropbox Transfer: Making simple even simpler Speeding up a Git monorepo at Dropbox with <200 lines of code
Open Sourcing Pytest Tools
Nipunn1313 · 2016-03-04 · via Dropbox Tech Blog

At Dropbox, we made the switch from testing with unittest to pytest. We love the features, fixtures, plugins, and customizability of pytest. To further improve our experience, we built a couple of tools ( pytest-flakefinder, unittest2pytest) for working with pytest and released them as open source.

We developed the pytest-flakefinder plugin to help with a common problem, flaky tests. Tests that involve multiple threads, or that depend on certain ordering can often fail at a fairly low rate. A few flaky tests aren’t a big deal, but with thousands of tests, they become a huge issue. We used to literally run pytest in a loop or sometimes just copy paste the test code multiple times to see if we could reproduce the failure. With this plugin we can easily have pytest run the test multiple times in a row. And if you combine it with -x --pdb you can just run it until it fails and get yourself a debugger ready to find out what happened. We now run flakefinder on updated tests in CI to detect flakiness proactively.

Another one of the key pytest features we love is assertion rewriting. This pytest feature allows us to see significantly more detailed error messages when asserts fire. In order to take advantage of assert rewriting, the tests must use a raw assert a == b rather than the unittest library’s idiomatic self.assertEqual(a, b).

Test output using unittest style assertions:

test/test_login.py:80: in test
self.assertEquals(login.call_count, 1)
E AssertionError: 0 != 1
assert login.call_count == 1

pytest output with raw Python asserts:

test/test_login.py:80: in test
E AssertionError: assert 0 == 1
E + where 0 = <MagicMock name='mock.desktop_login.login' id='140671857679512'>.call_count

When we made the switch to pytest, we had thousands of existing tests generally using the latter form. Fortunately, pytest is compatible with unittest asserts, so our test suite still passed. However, we weren’t getting the benefits of assertion rewriting everywhere. On top of that, we had different testing practices in our codebase, leading to some confusion.

We developed unittest2pytest to convert our existing unittest asserts to pytest rewrite-compatible raw asserts. It’s built on top of the lib2to3 library for automatic code rewriting. This library was able to safely convert most of our code automatically. There were a few hiccups with certain kinds of whitespace and inline commenting, which you can see in our issue reporter. unittest2pytest simply skips over converting things it doesn’t understand.

At Dropbox, we developed pytest-flakefinder and unittest2pytest to improve our experience with pytest. These tools are both open source now, so check them out if you use pytest or are considering switching.