Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am to write some one-off code in c#.net that will do some db manipulation of existing records and call a third party REST Api to update those records.

I proposed writing a unit test that does it. And running it in vs2012. My team mates were not too happy with the approach and preferred writing a console application to do it.

What does the community think? Which ones do you prefer and what are the pros and cons of each approach.

Update #1 - Exact scenario (to keep everyone happy) is as follows

An in-house API handles newsletter subscription for my website (well.. the website i work on). So these details are with this API (emails and their preference (subscribe or unsubscribe)). But to achieve certain things we keep a track of these preferences in our application db as well (SQL Server, as a table). Now there is some data in the applicaton's SQL db which is not in sync with the records that API manages. To do this, i want to be able to write a unit test/console app that will read some emails from a given list (maybe an excel), call the api to get preferences associated with those email ids and then update application's SQL db table.

Update #2 - Why i want to use unit test to preform this functionality

  1. I want to add this test/tests to my existing test project. This way i will have access to ALL Dtos and Contracts (and objects in general) which are used in my application. Saves me time repeating/duplicating any code that i may need into a separate console app.

  2. Since it will be part of the existing source control repo, i dont have to maintain a seprate project/application which i will have to if i do a console (if i want to share it with people)

share|improve this question
1  
The scenario seems too vague to give a reasonably complete answer. Is this a one-time database wide migration, a one-time adjustment to a small subset of [mysteriously] corrupted records, something that be ongoing, but very sporadic or periodic? In any case, a test should only be performed against test data, a copy or representative subset of live data. –  JustinC Jun 4 '13 at 12:15
1  
@JustinC - Please read my update above. The idea is to run this test to change db records on a COPY of Live data, once successful, create an patch script and then run it on Live db. –  nesh_s Jun 4 '13 at 12:48
    
@nesh_s The question says nothing of a copy, and I completely missed it in the comments when posting my answer. Can you edit the "exact scenario" with the real exact scenario? –  Izkata Jun 5 '13 at 11:33
    
why is this question closed? What is unclear? Where is the ambiguity? I thought the forum was to help people understand WHY to do things certain way and improve. If there were details missing, i was happy to add more if i was asked. how is it valid to snub questions from new members and just close them for a reason which is ambiguous, vague, incomplete. –  nesh_s Jun 5 '13 at 14:49
    
@nesh_s This isn't a forum, it's a question/answer site (see the about page for more information). The question can also be reopened if it's updated. As for ambiguity/incompleteness, see my previous comment - you don't seem to be giving us all the information. –  Izkata Jun 5 '13 at 16:04
show 4 more comments

closed as not a real question by Jim G., Martin Wickman, Bart van Ingen Schenau, gnat, Yusubov Jun 5 '13 at 13:29

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

7 Answers

A test is a test, and what you described is an application, not a test.

Don't write code that you don't want run again and again and again as a unit test. Write a console app, or a winforms app, or an add-in or whatever, but NOT as a test.

Feel free to write a unit test for your code, though. What you think is a one-off code will often wind up sticking around forever.

Addendum:

Your updates are describing an automated process that WILL be repeated, and on a regular basis. Not "some one-off code."

Anyway, as I said before, you should write the feature you need to process those updates as a program, not a test. If you want it to have access to all of the various aspects of your existing project, make it part of that project. Assuming it's an ASP.NET project, an "admin" page is the classic solution.

share|improve this answer
    
I understand its an application i am trying to write in a unit test (albeit a very tiny one). As for "Don't write code that you don't want run again and again and again as a unit test." i dont think this is entirely valid. Conversely what you saying is "Write code that you want run again and again and again as a unit test." which i dont think is a valid assumption (Scheduled Tasks??). What i am tryin to get out of this post is WHY not to do it. –  nesh_s Jun 4 '13 at 13:05
    
@nesh_s you will run your application whenever you need to sync. You will run your tests every time you change a character in your code. That's the difference. –  Florian Margaine Jun 4 '13 at 17:14
    
a unit test can easily be opened by its test framework and ran without user interaction. it's part of how most frameworks are designed, and if you make a destructive non-test as a unit test, you're telling a framework that happens to see the test to go ahead and run it. The reason not to do this is the same reason that you shouldn't put a gun away loaded. –  DougM Jun 4 '13 at 17:14
    
@florian - i understand the difference. what i dont understand is why you thought i didnt. i quite cant get the point you are trying to make here, apart from the obvious (which was not why i asked this question in the first place). –  nesh_s Jun 5 '13 at 8:12
    
@DougM - not the best analogy to explain. it is simple NOT to make this test run EVERYTIME all my normal tests run. This will be an ad-hoc, which runs in the realm of the test framwework as and when i move it. anyways i get the impression that unit-tests do have a very limited meaning for most. –  nesh_s Jun 5 '13 at 10:42
show 1 more comment

hang on - you want to write a unit test that actually performs the work you want doing??

It does seem to me that you've violating the principle of keeping it simple, by trying to fudge unit test framework to do something it wasn't intended.

Make a console app, it'll be easier to deploy to an environment that might not have your version of the dev tools and frameworks you use on it. (what's the chances you'll need to do this "one off" task again?)(don't answer that - we all know its practically a certainty if you make your code non-repeatable)

share|improve this answer
    
Yes. i actually want to write a unit test tht does this for me (read my update on what i plan to achieve). I dont know why it is entirely unheard of here :) (assuming the italics were for surprise). As to why i want to do it, please read my update to the main question –  nesh_s Jun 4 '13 at 12:57
    
@nesh_s well, I would say that all the DTOs and everything else should be extractable so that can be reused in a separate console app. If they're not, you have wider problems that trying to force everything to run in a test framework will not solve. You could refactor your dependencies so they can be reused, or you could write up your codebase for the DailyWTF :-) –  gbjbaanb Jun 17 '13 at 11:35
add comment

Is it a unit test?

some one-off code in c#.net that will do some db manipulation

Ok. Database manipulation doesn't mean database access. You may have used a mock of the database in order to concentrate on the manipulation itself.

of existing records

So the code should work for only a predefined set of data? If you're not creating data processing algorithm in general, but just a quick tool to process actual, well-known data, unit tests won't be very useful.

and call a third party REST Api

Ouch! Unless you mock this too, it becomes an integration test, not a unit test.

To conclude, you write unit tests if:

  • You mock both the database access and the calls to the REST API,
  • And you are writing code which is expected to work for any data in the future, not just one time for a known set.
share|improve this answer
add comment

I think you're looking at this the wrong way. What is the purpose of a unit test? To test that some piece of code works correctly. If that's not what you want to do, then don't use a unit test.

What you should do is to create a separate console application that references your other projects. This way, you can use all the code you already have. A good place for that application is probably in a new project in your current solution.

Another possibility, especially if you're going to write more of these one-off applications and each is going to be simple, is to use a LINQPad snippet for this. You can still reference your current code from LINQPad to avoid duplication.

share|improve this answer
add comment

In a comment, you said:

What i am tryin to get out of this post is WHY not to do it.

Unit tests are meant to run to check that code works as intended. Because of this, they are often (I wish I could say "always") used with continuous integration, and automatically run whenever a new commit was made to the code. This can be several times in an hour, or once per year.

So that's one good reason not to do it: You cannot guarantee when it will run.

From the question:

To do this, i want to be able to write a unit test/console app that will read some emails from a given list (maybe an excel), call the api to get preferences associated with those email ids and then update application's SQL db table.

This is not a test, this is a production application you are describing. Unit tests are designed to work on test data, and twisting them into something they were not meant for is just asking for trouble.

I want to add this test/tests to my existing test project. This way i will have access to ALL Dtos and Contracts (and objects in general) which are used in my application. Saves me time repeating/duplicating any code that i may need into a separate console app.
Since it will be part of the existing source control repo, i dont have to maintain a seprate project/application which i will have to if i do a console (if i want to share it with people)

Extract them out into a common codebase that both the primary app and the one-off console app will import from, using svn externals / git modules / whatever is appropriate for your version control. You can commit to them from the external/module without having to make a separate checkout, and others can reuse them in a simple and obvious way.

share|improve this answer
    
"This can be several times in an hour, or once per year." i can see that there is disconnect in what i am trying to ask and what the general understanding is (of the problem). So even though i dont neccesarily agree with majority of the points in the reply above, i agree that "Unit tests are designed to work on test data, and twisting them into something they were not meant for is just asking for trouble." I wish i could +1 your reply. –  nesh_s Jun 5 '13 at 10:47
add comment

This may be a case for further abstraction of your libraries/projects.

You say:

I want to add this test/tests to my existing test project. This way i will have access to ALL Dtos and Contracts (and objects in general) which are used in my application.

You should have no trouble getting access to your DTOs and contracts from a console application. If your DTOs and contracts reside in a separate assembly, you can simply reference that assembly in both your web project AND your console application. There is no need to rewrite any code.

You also say:

Since it will be part of the existing source control repo, i dont have to maintain a seprate project/application which i will have to if i do a console (if i want to share it with people)

Why wouldn't the console application reside in the same solution as your web project and unit tests? It acts on the same data and appears imperative for the web app to function correctly. It should live with the web app and be versioned with it. You'll also probably want to test the console application, so your solution would look something like this:

/solution
    /sharedcontracts
    /sharedcontracts.tests
    /webapp
    /webapp.tests
    /consoleapp
    /consoleapp.tests
share|improve this answer
add comment

So, you want to write some functional tests?

If you use unit tests framework, it will be simpler to add new tests, and you'll have functions (or macros) to do some tests. Of course, do not mix functional and unit tests, since unit tests have to be fast. Also, do not use mock classes, because you want to do black box testing.

Good thing about functional tests is they are repeatable, and it is simple to add them as a job in a continuous integration, and forget about them (until you break them).

On the other hand, if you write console app from scratch, it will take longer, and harder to maintain.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.