I'm working on a project that has client and server side. And I'm writing a "pre-check-in" tool that will validate a lot of our communication between client and server.
I already have unit tests on both sides, now I really want to test the integration between both.
Like a real client connection to the server and vice-versa.
I really want to go unit testing on this, but I'm having a really hard time figuring out how I can initialize the MMVMCross framework and my view model classes.
In another thread I've asked for help on my "console app" that runs the tests but it is also really hard to initialize the framework and it makes me loose the coolness of unit testing with Visual Studio and reSharper.
My view models use SQLite and HttpClient with async/await.
For instance: I can't find a way to instantiate a view model that would need this interfaces:
IChatService, IMvxMessenger, IDataService, ISettingsService
Some from the framework some from my own code.
I known and I'm trying to register my ones, on a TestFixtureSetUp, but off course this fails, as the MVVM base subsystem (ioc?) is not setup yet.
Some above services, like IDataService for instance, also needs ISQLiteConnectionFactory, IMvxMessenger, ISettingsService.
I know unit testing is supposed to be fast, but my idea is to put all this tests in a new Category, that I would run only before my check-ins and my buddy, server developer, would run before his check-ins.
What would be the best approach here?
Any hint, suggestions, things to investigate/study would help at this point, as I'm practically stuck on this one.
Sergio
For instance: I can't find a way to instantiate a view model that would need this interfaces:
IChatService, IMvxMessenger, IDataService, ISettingsService
Generally this would be done using Mock implementations and then calling the ViewModel constructor directly with those Mocks.
I'm having a really hard time figuring out how I can initialize the MMVMCross framework
In order to initialise the IoC part of the framework you can use the MvxIoCSupportingTest helper class -https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Test/Cirrious.MvvmCross.Test.Core/MvxIoCSupportingTest.cs
If you then need additional parts of the framework, then generally you should mock these in some way. For example, see how navigation is mocked in these two articles:
http://blog.fire-development.com/2013/06/29/mvvmcross-enable-unit-testing/
http://slodge.blogspot.co.uk/2013/06/n29-testing-n1-days-of-mvvmcross.html
If it helps, an example of this type of test is https://github.com/slodge/MvvmCross-Tutorials/blob/master/Sample%20-%20TwitterSearch/TwitterSearch.Test/TwitterViewModelTest.cs#L21
If this answer doesn't have sufficient information, please provide a bit more example code about the tests you are trying to write.
Related
I have read/watched so much about TDD & BDD recently that I really want to master it. I have been a developer that only writes code and then tests it from outside (like we always started). The problem seems to be in getting up and running with TDD. I want to just create a simple Winform app in which I want to show a list of something lets say products. I just don't know where to get started, should I write a test for controller first? the controller needs reference to view and service and so on so forth. ASP.Net MVC is built for testing therefore it is a bit easy to get started but Winforms are a real pain. Kindly give me some Videos (Most preffered) that show TDD in Winforms.
I have watched tons of videos that show you testing a class or feature but how do you test UI that does not support testing?
In short I want to know if anyone has been doing TDD for a while, how
does he/she do it in Winforms?
I have written loads of code that I just delete because I get stuck, Please help!
Here's how I do it for any kind of UI, be it Web or Winforms or WPF or Swing in Java or even a web service interface that's going to be used by another system.
Write the UI, and hard-code any data behind it.
Write a controller, and move the hard-coded data to the controller. The controller should just be presenting the data in a form that the UI can understand.
Your controller now has no behavior; just static data - but it's got the right API for the UI, and now you know how the UI wants to use it.
Write an example that shows how the UI will use the controller in the most basic form.
Make the example work.
Write another example that shows how the controller behaves differently in a different context.
Make the example work.
Those are your unit tests! If you know that your controller is going to need some other classes to collaborate with, you can mock those out too.
Once your collaborators are mocked out, you already know how the controller wants to use them. Again, you have the API for those collaborators already, because the controller is using them.
This is what we're doing when we talk about "outside-in" in BDD.
I'm new to TDD too, and just like you I'm trying to learn. Here's what I've come up with during my searches, maybe it will help you too:
Check out Roy Osherove's website, and also his book "The Art of Unit Testing". Check out the videos, there are some great ones, especially the "Pair Programming" section. His book was the single best book that I've read about unit testing and TDD, and the only one that I've read from cover to cover.
Check out some TDD katas. There are some on the web page I've suggested in the previous item. Check out how other people are solving the katas. It's really helpful.
Read about dependency injection.
If you want to TDD in WinForms, check out the MVP pattern. As far as I know, it's the de facto patten for separating UI from business code in WinForms.
Good luck with your search.
The controller is a good starting point. Extract the View public api to an interface an test the interaction of the controller with that interface using a Mocking Framework. You can do the same for the service layer too.
Also, I would take the bottom-up approach for this application and unit test the lower level layers before adding tests to the UI layer. On the UI layer I will write a set of Acceptance Tests using a BDD framework and use mocking frameworks to make those tests lightweight and to reduce the number of tests.
Good luck!
How to do TDD/BDD with asp.net 4.0 Web Forms? I have an existing website that has very large scale and we dont have any test with each change in database we have to guess what will break? I want to introduce unit testing please give me pointers?
A lot will depend on how your existing codebase is structured.
It can take a lot of work to retrofit Unit testing and especially TDD into a legacy project. Typically you'll find database and business logic residing in the code behind file of the web pages.
Use of interface types are your friend here as Visual Studio can generate Interface classes automatically for you. (Place the cursor over a class name, right click, select refactor and extract interface)
I would work towards separating your database code into a class library project of it's own. You can then specify the public interface through which the business logic etc can access the database. All other code should treat the database repository as a black box.
Create a factory to make your repository (based on that Interface), have it create a test type and a live type. The live type will link into your current database code. The test type will just return hard coded values. You can write tests using the live database, then you can write tests for the "test" database in a TDD manner.
Once they both match (all tests pass) any new database functionality is added by writing the test that runs on the "test" database first and then on the live database.
Remember all code should only use the Interface to the database not an instantiated live database class.
Once you've got the hang of the process you can delve deeper (if you wish) within the database code, but I would say that following the same process in separating and testing business and UI logic is more practical on a legacy project.
You may find that a pragmatic approach is to only separate out functionality following the process that I've described as you go to add new code. In other words before you add new functionality, separate out the code as described writing the tests that show that it passes (live and test version) then alter or add test for new functionality using whether the test passes or fails to guide your coding.
If covering all bases you want a test for failure, test for pass and maybe a test for exception scenario.
Good luck. It's not a job for the faint hearted (having had to do it many times in the past).
I am new to unit testing. Suppose I am building a web application. How do I know what to test? All the examples that you see are some sort of basic sum function that really has no real value, or at least I've never written a function to add to inputs and then return!
So, my question...on a web application, what are the sort of things that need tested?
I know that this is a broad question but anything will be helpful. I would be interested in links or anything that gives real life examples as opposed to concept examples that don't have any real life usage.
Take a look at your code, especially the bits where you have complex logic with loops, conditionals, etc, and ask yourself: How do I know if this works?
If you need to change the complex logic to take into account other corner cases then how do you know that the changes you introduce don't break the existing cases? This is precisely what unit testing is intended to address.
So, to answer your question about how it applies to web applications: suppose you have some code that lays out the page differently depending on the browser. One of your customers refuses to upgrade from IE6 and insists that you support that. So you unit test your layout code by simulating the connection string from IE6 and checking that the layout is what you expect.
A customer tells you they've found a security hole where using a particular cookie will give you administrator access. How do you know that you've fixed the bug and it doesn't happen again? Create a unit test for it, and run the unit tests on a daily basis so that you get an early warning if it fails.
You discover a bug where users with accents in their names get corrupted in the database. Abstract out the webform input from the database layer and add unit tests to ensure that (eg) UTF8 encoded data is stored in the database correctly and can be retrieved.
You get the idea. Anywhere where part of the process has a well-defined input and output is ideal for unit testing. Anything that doesn't is ideal for refactoring until it is well defined. Take a look at projects such as WebUnit, HTMLUnit, XMLUnit, CSSUnit.
The first part of testing is to write testable applications. Separate out as much functionality as possible from the UI. Refactor into smaller methods. Learn about dependency injection, and try using that to create methods that can take simple, throw-away input that produces known (and therefor testable) results. Look at mocking tools.
Infrastructure and data layer code is easiest to test.
Look at behavior-driven testing as well as test-driven design. For my money, behavior testing is better than pure unit testing; you can follow use-cases, so that tests match against expected usage patterns.
Unit testing means testing any unit of work, the smallest units of work are methods and functions., The art of unit testing is to define tests for a function that cannot just be checked by inspection, what unit test aims at is to test every possible functional requirement of a method.
Consider for example you have a login function, then there could be following tests that you could write for failures:
1. Does the function fail on empty username and password
2. Does the function fail on the correct username but the wrong password
3. Does the function fail on the correct password but the wrong username
The you would also write tests that the function would pass:
1. Does the function pass on correct username and password
This is just a basic example but this is what unit testing attempts to achieve, testing out things that may have been overlooked during development.
Then there is a purist approach too where a developer is first supposed to write tests and then the code to pass those tests (aka test driven development).
Resources:
http://devzone.zend.com/article/2772
http://www.ibm.com/developerworks/library/j-mocktest.html
If you're new to TDD, may I suggest a quick trip into the world of BDD? My experience is that the language really helps people pick up TDD more quickly. Particularly, I point you at this article, in which Dan North suggests "what to test":
http://blog.dannorth.net/introducing-bdd/
Note for transparency: I may be heavily involved in the BDD movement.
Regarding the classes to unit test in a web-app, I'd consider starting with controllers, domain objects if they have complex behaviour, and anything called "service", "manager", "helper" or "util". Please also try renaming any classes like this so that they are less generic and actually say what they do. Classes called "calculator" or "converter" are also good candidates, and you'll probably find more in the same package / folder.
There are a couple of good books which could help you too:
Martin Fowler, "Refactoring"
Michael Feathers, "Working Effectively with Legacy Code"
Good luck!
If you start out saying, "How do I test my web app?" that is biting off a lot at once, and it's going to be hard to see unit testing as providing any kind of benefit. I got into unit testing by starting with small pieces that were isolated, then writing libraries test-first, and only then building whole applications that were testable.
Generally a web app has a domain model, it has data access objects that do queries on a database and return domain objects, it has services that call the data access objects, and it has controllers that accept http requests and call the services.
Tests for the controllers will check that they call the right service method with the right parameters. Service objects can be mocks injected during test setup.
Tests for the services will check that they call the right data access objects and perform whatever logic they need to be performing. Data access objects can be mocks injected during test setup.
Tests for the data access objects will check that they perform the right database operation (query or update or whatever) by checking the contents of the database before and after. For dao tests you'll need a database, and a tool like DBUnit to pre-populate it before the test. Also your domain objects' getters and setters will get exercised with this test so you won't need a separate test for them.
Tests for the domain model will check that whatever domain logic you have encoded in them works (Sometimes you may not have any). If you design your domain model so it is not coupled to the database then the more logic you put in the domain model the better because it's easy to test. You shouldn't need any mocks for these tests.
For a web app the kind of tests you need to do are slightly different. Unit tests are tests which test a particular component of your program. For a web app, you would need to test that forms accept/reject the right inputs, that all links point to the right place, that it can cope with unexpected inputs etc. I'd have a look at Selenium if I were you, I've used it extensively in testing a number of sites: Selenium HQ
I don't have experience of testing web apps, but speaking generally: you unit test the smallest 'chunks' of your program possible. That means you test each function on an individual basis. Anything on a larger scale becomes an integration test.
Of course, there are going to be methods so simple that its not worth your time to write a test for them, but on the whole aim to test as great a proportion of your code as possible.
A rule of thumb is that if it is not worth testing it is not worth writing.
However, some things are very difficult to test, so you have the do some cost benefit analysis on what you test. If you initially aim for 70% code coverage, you will be on the right track.
If I'm having Data Access Layer (nHibernate) for example a class called UserProvider
and a Business Logic class UserBl, should I both test their methods SaveUser or GetUserById, or any other public method in DA layer which is called from BL layer. Is this a redundancy or a common practice to do?
Is it common to unit test DA layer, or that belongs to Integration test domain?
Is it better to have test database, or create database data during test?
Any help is appreciated.
There's no right answer to this, it really depends. Some people (e.g Roy Osherove) say you should only test code which has conditional logic (IF statements etc), which may or may not include your DAL. Some people (often those doing TDD) will say you should test everything, including the DAL, and aim for 100% code coverage.
Personally I only test it if it has logic in, so end up with some DAL methods tested and some not. Most of the time you just end up checking that your BL calls your DAL, which has some merit but I don't find necessary. I think it makes more sense to have integration tests which cover the app end-to-end, including the database, which covers things like GetUserById.
Either way, and you probably know this already, but make sure your unit tests don't touch an actual database. (No problem doing this, but that's an integration test not a unit test, as it takes a lot longer and involves complex setup, and should be run separately).
It is a good practice to write unit test for every layer, even the DAL.
I don't think running tests on the real db is a good idea, you might ruin important data. We used to set up a copy of the db for tests with just enough data in it to run tests on.
In our test project we had a special web.config file with test settings, like a ConnectionString to our test db.
In my experience it was helpful to test each layer on its own. Integrating it and test again. Integration test normally does not test all aspects. Sometimes if the Data Access Layer (I don't know nHibernate) is generated code or sort of generic code it looks like overkill. But I have seen it more than once that systematic testing pays off.
Is it redundancy? In my opinion it is not.
Is it common practice? Hard to tell. I would say no. I have seen it in some projects but not in all projects I worked in. Was often dependend on time/resources and mentality of the team / individiual developer.
Is it better to have test database, or create database data during test? This is quite a different question. Cannot be answered easily. Depends on your project. Create a new one is good but sometimes throws up unreal bugs (although bugs). It is depending on your project (product development or a proprietary development). Usually in an proprietary on site development a database gets migrated into from somewhere. So a second test is definitely needed with the migrated data. But this is rather at a system test level.
Unit testing the DAL is worth it as mentioned if there is logic in there, for example if using the same StoredProc for insert & update its worth knowing that an insert works, a subsequent call updates the previous and a select returns it and not a list. In your case SaveUser method probably inserts first time around and subsequently updates, its nice to know that this is whats being done at unit test stage.
If you're using a framework like iBatis or Hibernate where you can implement typehandlers its worth confirming that the handlers handle values in a way that's acceptable to your underlying DB.
As for testing against an actual DB if you use a framework like Spring you can avail of the supported database unit test classes with auto rollback of transactions so you run your tests and the DB is unaffected afterwards. See here for information. Others probably offer similiar support.
I must be doing something fundamentally wrong.
I am implmenting my repositories and then testing them with mocked data. All is well.
Now I want to test my domain objects so I point them at mock repositories.
But I'm finding that I have to re-implement logic from the 'real' repositories into the mocks, or, create 'helper classes' that encapsulate the logic and interact with the repositories (real or mock), and then I have to test those too.
So what am I missing - why implement and test mock repositories when I could use the real ones with mocked data?
EDIT: To clarify, by 'mocked data' I do not hit the actual database. I have a 'DB mock layer' I can insert under the real repositories that returns known-data.
Maybe your mixing your abstractions. maybe some of the helpers and logic that your talking about should be in your domain objects. Your repositories should be implementing a CRUD interface. So your domain logic should be using 8 actions from the repository. Good retrieve and Bad retrieve (exception thrown) are only two of the eight. One test, is how is the Bad retrieve handled in the domain object. The rest of the tests should be testing a Good retrieve.
Unit testing is meant to minimize the tested element -> test data route, in order to reduce search time if a bug occurs - the bug is either in the routine you test or the test unit and nothing else (well, maybe the OS or the compiler... but these are very rare).
Now imagine you made a database accessor module. The module seems to work ok. Then you make a config reader that reads from the database. Instead of a mock database accessor module unit test, you use your real database module on top of mock config data in the database test unit. It still seems to work OK. Now you add a GUI layer that uses the config object returned by the config reader unit. Instead of mocking the "boiled" config data you use the real module which apparently works.
And now your GUI stops working for a certain value. Where is the error? In the GUI, in the config reader, in the database accessor or in the values in the mock database?
In other words, you're not just testing the code you're writing, you're testing the real repository system as well, and if a bug is found you have an additional layer to analyze.
why implement and test mock
repositories when I could use the real
ones with mocked data?
I guess it really comes down to how much code coverage you think you need to have. If you feel the repository is sound and you can use it for testing, go for it. Perhaps the repository unit tests can be run prior to the mock database unit tests, so that you can use the real repositories for testing and feel confident that the testing is still valid.