I have one problem with most tutorials on how to introduce tests in legacy code. Almost all of them are testing an application that gets one input and produces one output. Sorry, but that is easy. Where is a video on how to introduce testing in windows MFC MDI application, where almost all components depend on each other; where there is no meaningful operation that does not include a query to the database? Where do I start with such legacy code? How to introduce regression tests in a non-deterministic application (meaning the same input does not always produce same output)?
it could be argued those kinds of tests aren't unit tests but integration or systems tests, and depending on the specific behaviors in test you might need to create in-memory database mocks all the way to mirroring full slices of the production environment in a cloud environment, say for example in Azure using Powershell scripts based on some configuration snapshot of the current production environment and testing the desired behavior against those
@@georganatoly6646 quite frankly, I prefer writing an in container test mock script (which e.g. sets up a database) to doing this in the C++ code from my experience easier to keep correct
1. Not every code is well testable. When you write new code you have to ensure it will be testable - this is an essence of good design. When you deal with legacy code you may have to refactor it in order to produce proper unit tests. If refactoring can't be done, you may not unit test your code at all, or your tests will be ugly and fragile (any little change or refactoring may brake them). 2. If there are dependencies such as queries to databases you have to do the following. First, make sure those queries are all encapsulated in corresponding class and do not mess with other business logic. Second, create mocks for classes which do queries with databases. Write a UT using those mocks to produce desirable behavior and impose expectations on how the mocks are used in the system under test. 3. Non-deterministic code is not so non-deterministic. If it produces different results from call to call it means it takes some other input somewhere else, e.g. time. Stub the platform functions which return time and provide your own implementations so that you have control over the factors which make your code behave non-deterministically.
34:25 I need to disagree here because I had multiple cases where the public interface still seemed to do the correct thing, but the private functions didn't but in a way which made the error only detectable via other means quite a long time later. Also testing private function saved me way more time than you might think.
It seems like the only way that could happen would be - the return is incorrect, the test is incorrect, or the function is creating untested side effects. (?)
Unit tests are good if you want to lock the code, make it hard to modify it. Do you want this? If not unit test are going to slow down the development process a lot.
This person is genius, he explains really well!! Thank you.
Glad you think so!
I have one problem with most tutorials on how to introduce tests in legacy code. Almost all of them are testing an application that gets one input and produces one output. Sorry, but that is easy. Where is a video on how to introduce testing in windows MFC MDI application, where almost all components depend on each other; where there is no meaningful operation that does not include a query to the database? Where do I start with such legacy code? How to introduce regression tests in a non-deterministic application (meaning the same input does not always produce same output)?
how can an input not produce same input ? If that happens how can you know the output is OK, even without tests ?
it could be argued those kinds of tests aren't unit tests but integration or systems tests, and depending on the specific behaviors in test you might need to create in-memory database mocks all the way to mirroring full slices of the production environment in a cloud environment, say for example in Azure using Powershell scripts based on some configuration snapshot of the current production environment and testing the desired behavior against those
"Working effectively with legacy code" by Michael Feather, you'll certainly love it, gl hf :)
@@georganatoly6646 quite frankly, I prefer writing an in container test mock script (which e.g. sets up a database) to doing this in the C++ code
from my experience easier to keep correct
1. Not every code is well testable. When you write new code you have to ensure it will be testable - this is an essence of good design. When you deal with legacy code you may have to refactor it in order to produce proper unit tests. If refactoring can't be done, you may not unit test your code at all, or your tests will be ugly and fragile (any little change or refactoring may brake them).
2. If there are dependencies such as queries to databases you have to do the following. First, make sure those queries are all encapsulated in corresponding class and do not mess with other business logic. Second, create mocks for classes which do queries with databases. Write a UT using those mocks to produce desirable behavior and impose expectations on how the mocks are used in the system under test.
3. Non-deterministic code is not so non-deterministic. If it produces different results from call to call it means it takes some other input somewhere else, e.g. time. Stub the platform functions which return time and provide your own implementations so that you have control over the factors which make your code behave non-deterministically.
Good introduction based on an existing project.
where to find slides?
Thank you Ben, that was instructive.
34:25 I need to disagree here because I had multiple cases where the public interface still seemed to do the correct thing, but the private functions didn't but in a way which made the error only detectable via other means quite a long time later.
Also testing private function saved me way more time than you might think.
It seems like the only way that could happen would be - the return is incorrect, the test is incorrect, or the function is creating untested side effects. (?)
Author::RetitleVideo(“How to use Google Test”);
Thank you for helping with my homework!
Unit tests are good if you want to lock the code, make it hard to modify it. Do you want this? If not unit test are going to slow down the development process a lot.
Like # 2^8.
You put us too deep into your boring project with parsers and tokens