Questions around TDD familliarity among Rustaceans


#1

Hello !

I’m writing a longer article on doing outside-in-tdd in Rust, and would love to know how TDD is seen among Rustaceans. Pelase bear with me and my questions here :slight_smile:

The article would be starting with crate level tests and drilling down, via collaboration tests down to small unit tests at the ‘leaf’ type level.

How familliar are the terms I used to you ? Do you feel that TDD is strong in the community ?
When you develop in Rust, do you test-drive ? How easy do you feel it is, do you lack any tools ?
Would you be interested in reading a longer writeup on the above ?

thank you ! :slight_smile:


#2

I’d say that testing plays a massive part in Rust development! The fact that it’s so easy to add a test containing a couple assert!()'s and then run it with cargo test means the barrier to entry is next to nonexistent. It also helps that the functional nature of Rust means you hardly ever need the complicated mocks or setup/teardown that you’d use in other languages. 99% of the time you’ll never need a mock, but even if you do you can just make your function generic and use traits.

I’d also recommend you mention the pretty-assertions crate. It’s a great little library for making it easy to see the difference between what you got and what you expected it to be.

Something that can be a bit annoying is getting CI set up so it runs your tests automatically. Even though I must have written dozens of .travis.yml or gitlab-ci.yml files for Rust projects by now it still takes me several goes before the CI service does what I want (run tests and push generated docs to GitHub/Gitlab Pages).


#3

I find it odd that people want to write on a subject without getting dirty themselves. Not just you, but I have found a lot of posts like that. The problem is you will take opinions from others which may end up in biased or half-baked thoughts.


#4

Heyo !
It wasn’t my intention to come as this, apologies for that.

I am in the middle of intensive pairing on https://github.com/tetrus-ai/tetrus and other projects with some awesome people and we’re going to write about lessons learned there, as the basis for the article.

I am truly curious what people find difficult and what is the attitude towards TDD in general. Having this knowledge will allow me to, hopefully, structure the article better :slight_smile:

thanks !


#5

Yah i know. Just saying it is better to try it out.


#6

I disagree. It’s not odd at all.

A person new to Rust would need to learn Rust and its new concepts (traits, lifetimes, borrow checking, etc.) before they are able to make any judgement. Not everyone can spare the time and effort required to learn new languages and their associated ecosystems.

I welcome such posts since they spark discussion that ultimately benefits the community.


#7

Learning is different from presenting an opinionated view on a subject.


#8

I read his post as saying “I’recently done this myself, and going to write an article about it; I’d love to get some broader community feedback so I can match my article to the community background

As for the original request:
I am familiar with test-driven development from the java world. I think Rust’s “basic” support for tests is better than several third-party runners in other languages, so Rust definitely has a head start.
I’m not so sure about “outside in” TDD, since I usually do “inside out”, and then lose focus after the unit tests.
Count me as one of the many many people doing TDD badly :wink:


#9

The concept of Top Down Development is well drilled into my head together with Structured Programming.

On-topic; Articles should cover implicit tests as well as explicit. IDEs “spell-checking.” How rust errors are found even before you compile.


#10

This was exactly my intention here, thank you for putting it into words :slight_smile:


#11

I was thinking more of Test-Driven Development there, but because it’s outside-in one might say it’s close to Top-Down :slight_smile: Apologies for using just the acronym itself.

That’s a very good suggestion, thank you :slight_smile:


#12

Ah my bad. Thought it was one of those “i need to write about X and don’t know much about it so I’ll paste your opinion as mine” post you often see online. Apologies :smiley:


#13

If you write tests and then develop, then you must already have set your API in stone. That seems like a bad idea, and stops you refactoring your API until you find the ‘natural’ API for the problem in the target language.

Also, given that tests generally have poor coverage, if you code only to get your tests to pass, then you’ve probably only handled a proportion of the problem space.

But maybe I have misunderstood the concept.

(BTW, implementing an influxDB line protocol parser just now, I wonder how someone could have ended up with such a catastrophically broken escaping situation. And I guess it could well have been one of these Agile coding practices, or test-driven-development or something like that – rather than just designing it properly and anticipating future needs or writing a simple grammar from the start. This is an example of something which does not handle the full problem space, but probably passed all its tests all the way through development.)


#14

Typically, one would write just one test, see that it fails, then write just enough implementation to make it pass.

The process involves a lot of refactoring, so a strong refactoring IDE is very useful. It also puts the developer in the shoes of the user for much of the development cycle, which I have found makes for an improved API as the end result.


#15

How familliar are the terms I used to you ?

Most were familiar; outside-in less so, collaboration tests, not at all.

Do you feel that TDD is strong in the community ?

Thats tough to answer, both because Rust is so young, and given the culture of the systems programming industry at large, which, IMHO, does not place nearly enough emphasis on testing at all, let alone TDD or BDD.

But overall, I’d say there is a healthy interest in the Rust community. I’ve found that the Rust community is a bit more receptive to doing things correctly, vs. just “getting it done”. That’s nice.

Recently I was looking for a mocking library for my project. I tried every one of them on crates.io, but found that most were not really suitable for a medium-to large-scale project.

The fact that there were choices available says something healthy about the community, so I’m optimistic. I settled on galvanic-test and galvanic-mock; together they let me write tests first, reduce boilerplate, and mock my dependencies.

The problem is, the IDE’s are not great at refactoring yet. I use JetBrains CLion with the IntelliJ Rust plugin. The test_suite! macro that galvanic-test has me write my test in effectively disables all syntax checking. Any errors I generate are “somewhere” in the macro… tl;dr: there is quite a distance to go before I would consider the testing tools and development ecosystem to be at “1.0”, but we’re well on our way.

Would you be interested in reading a longer writeup on the above ?

Absolutely! Thank you for bringing up the topic–I think there are many of us who are always interested in learning new things from others who’ve faced similar challenges. :slight_smile:


#16

:x:

I only have a vague understanding of TDD as “writing the tests before the code.”

Ehhhhh. For TDD specifically, I’d say no? My personal thoughts on the matter align with @jimuazu; requirements often change during implementation as a matter of practicality, and most edge cases do not become clear until I actually write the implementation.


TDD aside, I consider the simple fact that rust has unit tests embedded into the language to be one of its killer features. By which I mean, rust is pretty much the only language I ever write tests in for personal projects, because I don’t have to spend time shopping around for the ultimate testing framework and learning how to use it.


#17

I guess it depends on how people work best.

Personally I like to get the problem into my head, try various designs, and then start expressing it as code, and keep on refactoring and rewriting and changing stuff until it is all clean and minimal and theoretically fine. I work lots of difficulties out at the coding stage. I also document at this stage, and if something is hard to explain, that’s also a sign that the code interface needs simplifying. Then knowing my weaknesses and the difficult areas of the code, I write tests to stress all of that.

However, if someone prefers to think in concrete examples, then maybe test-driven-development helps them reason about the problem and incrementally build up a solution. If that works for them, then great! I do think it’s necessary to step back and take a big-picture view now and then, though.


#18

That’s an awesome set of responses right there, thank you :slight_smile:

As for the style and the practice - I’m not sure how much of the article to make about the introduction to the concepts and how much make it about Rust itself yet.

As for the mocking libraries on crates.io - I tried double and it was okay for what I needed at the time.

For the article itself - I’m torn between showing how to hand-roll a mock using a trait and a struct and just using a library as well.

For the style - I was thinking to show something along the lines of Sandro’s - https://www.youtube.com/watch?v=XHnuMjah6ps , while I may not agree with some of the smaller choices he makes - the overall flow is something very similar to what I tend to do at work and what I would liek to show done in Rust.

thanks again - this helps me a lot :slight_smile:


#19

… requirements often change during implementation as a matter of practicality, and most edge cases do not become clear until I actually write the implementation

That are exactly the problems where TDD tries to and could really help in practice :D.

But it’s somewhat a hard way to get there. Personally, I started it three times and now use it most of the times. The interesting thing is, that I do not work test driven while using rust, yet. I used to do TDD with Java, C, Javascript and Ruby. For me it helps to focus on the important things and driving the overall design without over engineering, but that may not work for everyone.


#20

People often interchange TDD & Writing Tests. A lot of benefits obtained by following TDD can also be obtained by writing tests after code.