-
Notifications
You must be signed in to change notification settings - Fork 1.7k
High level integration tests #374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a4f1a05
to
c90c0f7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Michael-F-Bryan I'll try to look closer and run these tests on Monday when I have access to PC. On cursory glance lgtm 😃
tests/integration_tests.rs
Outdated
/// Read the contents of the provided file into memory and then iterate through | ||
/// the list of strings asserting that the file contains all of them. | ||
fn assert_contains_strings<P: AsRef<Path>>(filename: P, strings: &[&str]) { | ||
println!("Checking {}", filename.as_ref().display()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really need the tests to write to stdout?
also why the need for freestanding println!();? println! is able to take any format string including newlines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for debugging. Basically when the test fails you won't see the full context of the failure, which in this case would include the file name it failed for, the contents of the file, and the text it's looking for. Normally stdout will get thrown away on a passing test, but when the test fails it'll show you all the information printed out and make identifying why the test failed a lot easier.
I guess you could include those in assert!()
's panic message, I've just done it this way out of habit. I can easily swap to printing everything in assert message if you want, should I do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right analyzing the code on mobile is not ideal ;). In general I prefer plain asserts but I'm good either way in this case. But please fix the empty printlns. I'll check the rest later this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I usually prefer plain asserts too however after writing out two or three I found I was copy/pasting the exact same set of assertions for each test and pulled it out into a function to make it easier to understand and read the tests.
Yeah, looks like those println!()
statements will need to go.
Can we separate the tests into multiple files each testing one specific domain? I don't recall how cargo handles integration tests. If I remember correctly, cargo treats each file in the I haven't played with tests in Rust enough to answer those questions. |
You can import any module, common file can live even in the |
Oh nice! I was planning to do some ugly stuff with I don't particularly mind having to do Also, can you guys think of any more integration tests which should be added to this PR? I'm looking for things which are easy to determine with something like |
@azerupi, any chance you can review this and let me know what you think of it or if any of the tests could be written better? Once this base PR is merged, adding more integration/regression tests on top of it will be a good target for new contributors. Instead of adding more tests to the PR I think we could create separate issues and post them on the TWIR Call For Participation thread. How does that sound? |
Yes, I'm checking it out now :)
Absolutely, tests would make very simple and isolated first issues. Especially if the ground work is already done and a couple of examples are present. |
tests/helpers.rs
Outdated
use tempdir::TempDir; | ||
|
||
|
||
const SUMMARY_MD: &'static str = "# Summary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an idea for maintainability:
We could make a simple directory with a dummy book like:
tests
├── config.rs
├── helpers.rs
├── init.rs
├── jsonconfig.rs
├── rendered_output.rs
├── test-book
│ ├── SUMMARY.md
│ ├── conclusion.md
│ ├── first
│ │ ├── index.md
│ │ └── nested.md
│ └── second.md
├── testing.rs
└── tomlconfig.rs
and then include the files like this
static SUMMARY: &str = include_str!("test-book/SUMMARY.md");
It makes it easier to edit and expand the book when we add more tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, since you convert to bytes later you can directly use ìnclude_bytes!()
tests/helpers.rs
Outdated
/// `assert!($TEST_STATUS)`. If you want to check MDBook's testing | ||
/// functionality, `$TEST_STATUS` can be substitute for either `true` or | ||
/// `false`. This is done using the `passing_test` parameter. | ||
pub fn create_book(passing_test: bool) -> TempDir { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little worried that we will end up with a huge number of arguments for this function in the future.. Currently there is only one argument passing_test
, but as more tests are added I am afraid that more arguments will appear too.
Maybe we should make this a builder struct with a good set of default options? In the simplest case we will have to call BookBuilder::create()
but in more complex scenarios, when we want some variation, we can just pass the arguments that need changing. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the BookBuilder
idea! It'll make things a lot easier in the long run, and also integrates quite nicely with your earlier dummy book directory comment.
tests/init.rs
Outdated
|
||
|
||
#[test] | ||
fn run_mdbook_init() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could add one or two lines of comments to explain what each test does?
It's easier if people don't have to read the code to understand what exactly the test is asserting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. run_mdbook_init
is a pretty useless name. I'll rename it to something longer like base_mdbook_init_should_create_default_content
.
tests/init.rs
Outdated
} | ||
|
||
#[test] | ||
fn run_mdbook_init_with_custom_args() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe the name can reflect that it specifically tests the source and output destination?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed the changes. This is a really great PR 🎉
I left a couple of comments for possible improvements. I think the names of the tests do not always reflect what they are testing. But that can be changed later.
I pulled the dummy book generation out into a Hopefully the names will be a bit easier to understand as well. I was probably being lazy when naming them before, assuming anyone checking up on a failing test would have the test in front of them and would understand it at a glance. |
Perfect! Thanks a lot! |
I didn't have time to really look into these changes (sorry :( ) but these look great! Excellent Work 💯 @Michael-F-Bryan |
High level integration tests
To make the job of merging #371 in with the rest of
MDBook
a bit easier I thought I'd add some really high level integration tests. These serve more as "sanity tests" than anything else. They're meant to exercise the entire library as a whole, doing things like:SUMMARY.md
is parsed correctly and you can build a valid bookmdbook init
will create a new book directory with sane defaults