Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for...
-
Upload
neal-maurice-sullivan -
Category
Documents
-
view
213 -
download
0
Transcript of Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for...
![Page 1: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/1.jpg)
Refactoring & Testability
![Page 2: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/2.jpg)
Testing in OOP programming
No life in flexible methodologies and for refactoring-infected developers without SOME kind of AUTOMATED tests
Tests are not a panacea, don't be categorical and skeptic. Tremendous use when possible to write
JUnit is a tool, so "не забивайте гвозди штангенциркулем"
Unit testing forces as to refactor!!!
![Page 3: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/3.jpg)
Unit testing benefits (1 of 2)
Can be applied to incomplete application
JUnit is the first User of your code!
Kinds of tests Unit->Integration->Function->Stress
Characteristic is the amount of application build already
Makes me confident that I prevent my peer developers and QAs from finding tedious errors in my code.
Less code to debug under test (as opposed to functional tests)
![Page 4: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/4.jpg)
Unit testing benefits (2 of 2)
Can simulate errors
Test not only successful path (as integration test basically does), but the scenario when something can fail!
Testing exceptions
Can act as a perfect and up-to-date documentation
Encourage us for refactoring! Probably the most important advantage.
![Page 5: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/5.jpg)
Example. Testing exceptions:
try {
methodWhichThrowsException();
fail(“Description”);
} catch(ApplicationException meaningfulNameExpected) {
assertNotNull(“Explanation why expected”,expected)
}
![Page 6: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/6.jpg)
Mocking
Programming on interfaces vs. concrete classes
Subclassing from concrete classes is a testing smell
If I subclass and override a method, what do I actually test?
MockObjects.com (JMock)
No! business logic. The mock should 100% comply to contract under CURRENT test. JMock is well suited for this rule.
![Page 7: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/7.jpg)
Example:
Testing e-mail service.
![Page 8: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/8.jpg)
When to use mocks
Notes on page 4
![Page 9: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/9.jpg)
Too many mocks? Hard to setup a test?
Mock lower OR refactor!
If a big framework has single but very smart method doWork() it's most likely a bad idea to test it
Test may be skipped if the method's contract is based solely on other contracts
![Page 10: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/10.jpg)
Example:
Shopping cart test (com.luxoft.tests.exercises.shoppingcart)
![Page 11: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/11.jpg)
Refactoring
Hardness to write (set up) unit tests FORCES us to simplify (factorize) the method or class or module.
Bad code is impossible to well unit test!
there is one-to-one dependency between good code and ability to write good tests
Code smells (detect manually or by means of PMD, etc.) Writing tests
![Page 12: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/12.jpg)
Refactoring DON’Ts (1 of 3)
Make Your Own Dependencies
Heavy Duty Constructors
Depend on Concrete Classes
Conditional Slalom. if-branches and switch statements
Depend on Large Context Objects
Use Statics
Use Global Flags
![Page 13: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/13.jpg)
Refactoring DON’Ts (2 of 3)
Use Singletons Everywhere
Use Primitives Wherever Possible
Look for Everything You Need (Law of Demeter)
Couple functional code directly to the external systems it depends on
Mix Object Lifecycles
Side Effects
![Page 14: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/14.jpg)
Refactoring DON’Ts (3 of 3)
Create Utility Classes and Functions/Methods
Create Managers and Controllers
Do Complicated Creation Work in Objects
Utils!
Final Methods
Handcuff your users to Specific Types
Use static initializes
![Page 15: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/15.jpg)
Example. Don’t depend on Large Context Objects:
class Mechanic {
Engine engine;
Mechanic(Context context) {
this.engine = context.getEngine();
}
}
![Page 16: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/16.jpg)
Example. Violate the law of Demeter:
class Monitor {
SparkPlug sparkPlug;
Monitor(Context context) {
this.sparkPlug = context.
getCar().getEngine().
getPiston().getSparkPlug();
}
}
![Page 17: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/17.jpg)
Inversion of controls & objects construction
Hollywood principle vs. factory method principle
Collaboration graph and construction graph
Remove new operators from application code as much as possible
Conclusion: separate classes with business logic and factories which create classes
![Page 18: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/18.jpg)
Example. Avoid new op. for testability:
class House {
private final Kitchen kitchen = new Kitchen();
private boolean isLocked;
private boolean isLocked() {
return isLocked;
}
private boolean lock() {
kitchen.lock();
isLocked = true;
}
}
![Page 19: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/19.jpg)
Benefits of IoC
Allows us to mock in tests
Allows us to use single instance of a class (saves us memory)
Shortens the methods and make them more precise (only business logic).
Real isolation.
![Page 20: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/20.jpg)
Inversion of controls. Conclusion
It’s good both for tests and for code’s health to:
separate the business logic from factory code to create required objects (for that business logic)
Doing so is really boring! Let the computer do boring stuff.
Use IoC containers
Dependency injection (wiring) Use empty, param-less constructors. Use setters!
![Page 21: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/21.jpg)
Refactoring for testability. Final thoughts
Consider IoC vs. factory method
Example: Isolate system resources getRemoteDataObtainer()
Test coverage and test quality
100% coverage does not mean that the method is 100% tested. Example.
Test quality measurement tools
Clover Jester/Muclipse
Oil detector in a car’s engine
![Page 22: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/22.jpg)
When Unit tests are good? (1 of 2)
Continuous and automated
Hudson / Email reports
Fast, easy to run
Written early to force Refactoring and detect design errors
No real opportunity to use integration tests
When code is good writing tests is fun. Should be easy
![Page 23: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/23.jpg)
When tests are good? (2 of 2)
When there a lots of tests!!!
We MOCK a contract, i.e. believe that a mocked method follows the contract. Test that!
Test as less code outside of the method under test as possible.
Ideally:
test=(test_method_code) + (private_methods) + (mocks)
![Page 24: Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.](https://reader036.fdocuments.us/reader036/viewer/2022070404/56649f345503460f94c51ed1/html5/thumbnails/24.jpg)
Unit tests is a must activity for a developer
Unit tests are not even a way to test code, but for a developer is a very much a way to develop perfect code
Just try!