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

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
博客园_首页
博客园 - 【当耐特】
V
Visual Studio Blog
博客园 - 叶小钗
月光博客
月光博客
美团技术团队
J
Java Code Geeks
小众软件
小众软件
Y
Y Combinator Blog
博客园 - Franky
Martin Fowler
Martin Fowler
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG

Nik Ogura

Writing for Generation Ships | Nik Ogura Load-Bearing Humans | Nik Ogura Your Hiring Pipeline Has the Same Bug as Your Deploy Pipeline | Nik Ogura Nice People Who Give Us Money | Nik Ogura Gambling on Failure | Nik Ogura DDCRI: Declarative, Deterministic, Continuously Reconciling Infrastructure | Nik Ogura Stop Holding Out for a Hero | Nik Ogura Don't Paint Yourself Into a Corner | Nik Ogura Most Infrastructure as Code Is Broken — and Reconciliation Is Only Half the Reason | Nik Ogura Continuous Acceptance Tests | Nik Ogura There's More Than One Way to Get Observability Right | Nik Ogura Put Dex In Front of Google OAuth | Nik Ogura Incident Management | Nik Ogura C-Style Thinking vs Go-Style Thinking | Nik Ogura 'Can' vs 'Does' | Nik Ogura Control Repositories | Nik Ogura Trunk-Based Development | Nik Ogura Web3 Is Just Infrastructure With a Hoodie | Nik Ogura "Design Me a Highly Resilient Database" | Nik Ogura Security Is Infrastructure | Nik Ogura Metrics, Logs, Traces, and Events: What's Actually Different | Nik Ogura Distributed Tracing: A Practical Guide | Nik Ogura Prometheus and OpenTelemetry: How They Fit Together | Nik Ogura Puppets and Octopi: Why Top-Down Orchestration Hits a Wall | Nik Ogura The Best Dog Trainer in the World - Or Why Getting Better Isn't Helping | Nik Ogura FluxCD vs ArgoCD: Architectural Comparison | Nik Ogura GitOps | Nik Ogura GitHub Actions Reference Implementation | Nik Ogura Shell Functions | Nik Ogura Engineering Standards | Nik Ogura
TDD (Test-Driven Development) | Nik Ogura
2020-07-17 · via Nik Ogura

What

TDD is the coolest thing since sliced bread. Maybe even since before that. Wikipedia has a good, if dry explanation. Read it!

I’ll add that it’s not so much that you have to write the tests before the code- which let’s face it- is often a pain in the neck, especially if you’re writing something new, and you’re not sure yet which direction you’re going.

It’s more that you need to alternate between tests and code. Why? Partially so that you actually write the tests and not forget about them in the rush to get a MVP going, but also so that you write code that can be tested.

This is huge. Rigorously following TDD as much as possible makes you write code in discrete units that you can test individually at first, and then later in groups. It’s absolutely priceless for finding problems quick, fixing them, and developing confidence about the state and reliability of your code base.

Why

Think about it this way. How do you know that a line of code works? You test it somehow. You can eyeball it, and that works great, but once you’re done, that test is lost. It could be repeated, but only by someone with the time and knowledge to look at it and know that it’s working correctly.

If instead, you teach the computer how to spot that thing you just eyeballed, why, then that test goes into the pile and we’ve forever captured that insight. We can run it every time we run the test suite. We can check that potential regression every time we examine the code, both personally and on the CI server. Very quickly these little ‘obvious’ tests (which are not always obvious to people not as into the problem space as you are when you’re writing the code) pile up and soon we have a really strong code base that we can trust.

So, please write tests. Lots of them. Any time you have something of interest that you’d want to check, teach the machine how to test that thing, and we’ll all benefit.

How

I actually do most of my development work (Java, Python, Chef) in tests. I acquired the habit in Java Spring development, where getting the same thing that’s happening in your IDE to work on the command line or on the CI server- thus proving it actually works- can be a real trick. It’s possible, but it’s painful, and you really don’t want to do it. Once I got used to it, and started to depend on the benefits of TDD, I realized it applies equally to any language.

I’ll write code in a test- even if it’s something quick, dirty or experimental, hit shift + f10 (which in IntelliJ runs whatever test you have activated in the testing dropdown) and watch it go red or green out of the corner of my eye while addressing the next task.

In the beginning, I’ll just print to STDOUT, and eyeball the result (it shows up in the test results window). Then I’ll put the things I’m eyeballing into test fixtures that output the ‘right answers’ and change the test to compare A with B. That way, every ‘eyeball operation’ is captured for posterity. ‘Posterity’ being me 10 minutes later when I decide to refactor things radically in response to the moment’s latest ‘great idea’, and now I have to be sure the rest of the code still works.

It works well while exploring a new API- something I seem to be doing all the time. My ‘investigation’ is saved, so when I’m distracted by a question or request from a colleague I don’t lose as much ground. The commands or constructs I’m exploring are easily copied from the test into the library I’m writing with a couple of keystrokes (I’m addicted to the IdeaVim plugin. Even though I’m using an IDE, my fingers think I’m just using Vim).

Once the code is massaged into it’s finished state, that whole investigation becomes frozen as a real test. It’s a great way to capture your output. Your investigation history is there, captured in code. It’s way more intelligible than digging through your bash_history or trying to recall how you did that clever thing you seem to recall doing last week.

I can’t tell you how many times I’ve gone back and read my tests to remember how exactly I intended a project to work. This applies to other people’s projects too. One of the first places I look to figure out how a library works (after our buddy google that is) is it’s test suite. If it’s a reputable project built and maintained by dedicated professionals, it will have a comprehensive test suite. Real developers write tests.

Once your IDE is configured to use the correct interpreter or environment, the tests will use that env by default- and the CI system is also set up to build and use the same env checked into the project (via requirements.txt or pom.xml, et al.). We all stay on the same page by default, and most everything just works.

Anyway, that’s the speech. If you’re going to contribute to a project I’m steering (and the more the merrier), please write tests to go along with your code. If you don’t, not only are you tragically uncool (all the cool kids write tests), but if I’m reviewing your contribution, I’ll reject code that doesn’t include solid tests. I’m a jerk that way.

Resources

  • Wikipedia - Good explanations, if a little dry. Don’t let it scare you.
  • Test-Driven Development By Example - It’s only available in the dead trees version. I wish this was available in an electronic format. Maybe someday. I’ve seen other books that have been searched for over and over eventually converted to ebooks. The Preface is available online however, and is a great read. Check it out.
  • Test-Driven Development with Python - This one is good too, but it’s written for use with Django, (a web framework) and Selenium (A web browser automation engine). Both are great tools, and it’s a great source of technical and philosophical information, but for the beginner it can be a steep learning curve.
  • Behavior-Driven Testing - TDD taken to the next level, and expanded beyond pure code.