views:

476

answers:

2

Hi all! My intend is to create a simple easily debuggable console application which will be the template ( or starting point ) for test driven developing single classes in C#. The purpose is to have a simple folder where this console app will reside and just copy paste the folder open the new project and start writing the new class. As soon as the class all functionalities tested ( Preferably the tests should be in the same file ( or at least namespace ) the class will be allowed to go into the larger project. I am using NUnit and log4net. If you do you this kind of "small test driven unit building " approach how have you implemented it. Please, post some code or explanation. If you do not use, please provide explanation why? Here is the code ( the config data is also pasted as comments ... )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;
using NUnit.Framework;

namespace NUnitSimple
{

  class TheClassToTest_Substractor
  {

    private static readonly ILog logger =
         LogManager.GetLogger ( typeof ( TheClassToTest_Substractor ) );



    public static void Substract ( int intToSusbractFrom , int intToSubstract , ref int intTheResult)
    {
     intTheResult = intToSusbractFrom - intToSubstract ; 
    }


    static void Main ( string[] args )
    {
      DOMConfigurator.Configure (); //tis configures the logger 


      logger.Info ( " START " );
      logger.Info ( " Hit a key to exit " );
      Console.ReadLine ();


    } //eof method 



  } //eof class 

  [TestFixture]//telling NUnit that this class contains test functions 
public class TestTheClassToTest_Substractor
{ 

     [Test]//telling NUnit that this function should be run during the tests 
    public void TestSubstractOk() 
    { 
       int intToSusbractFrom = 10 ; 
       int intToSubstract = 4 ; 
        int intTheResult = 0 ;
       TheClassToTest_Substractor.Substract ( intToSusbractFrom , intToSubstract , ref intTheResult ) ;
        Assert.AreEqual (  6 , intTheResult);
    }



     [Test]//telling NUnit that this function should be run during the tests 
     public void TestSubstractNOK ()
     {
       int intToSusbractFrom = 10;
       int intToSubstract = 4;
       int intTheResult = 0;
       TheClassToTest_Substractor.Substract ( intToSusbractFrom, intToSubstract, ref intTheResult );
       Assert.AreNotEqual ( 3, intTheResult );
     }

} //eof class 


} //eof namespace 




#region TheAppConfig
/*
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net"
         type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
      <param name="File" value="Program.log" />
      <param name="AppendToFile" value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="[Header] \r\n" />
        <param name="Footer" value="[Footer] \r\n" />
        <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
      </layout>
    </appender>

    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR" />
        <foreColor value="White" />
        <backColor value="Red, HighIntensity" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>


    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.2.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionString value="data source=ysg;initial catalog=DBGA_DEV;integrated security=true;persist security info=True;" />
      <commandText value="INSERT INTO [DBGA_DEV].[ga].[tb_Data_Log] ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />

      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout" value="%thread" />
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout" value="%level" />
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout" value="%logger" />
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%messag2e" />
      </parameter>
    </appender>
    <root>
      <level value="INFO" />
      <appender-ref ref="LogFileAppender" />
      <appender-ref ref="AdoNetAppender" />
      <appender-ref ref="ColoredConsoleAppender" />
    </root>
  </log4net>
</configuration>
 */
#endregion TheAppconfig

#region TheXmlReferingToTheNUnitAndLog4NetInNUnitSimple.csprojFile
/*
     <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\Log4Net\log4net-1.2.10\bin\net\2.0\release\log4net.dll</HintPath>
    </Reference>
    <Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
 */
#endregion
A: 

I don't really see what the benefit is over including the new class in the existing project, including the new test class in the existing test project, and running the tests there.

Why introduce a console app? Do you really need to run the tests from a console app rather than from one of the existing test runners? (Don't get me wrong, I'm a big fan of console apps - I just don't see how they fit in here.)

Jon Skeet
The benefit is complexity management. After 100 000 lines of code in the big project even simple utility class might disturb something even it is designed according to best practices for single responsibility etc. I am working currently on web application and the code base of the current project is huge ( at least for me: ). So the purpose would be to later on create the simple Web App also ...
YordanGeorgiev
Sounds like the main project needs to be refactored into packages. Terribly important as it lets you do your unit testing much more simply.
Tetsujin no Oni
If adding a new class which doesn't reference anything else break your project, I'd say you have bigger problems than unit testing.
Jon Skeet
+2  A: 

Rather than set up a a project and then cut and paste, why not look at a script tool like Tree Surgeon to set up a project structure. This will set up your solution, projects and project folders. It includes functionality for both nUnit and nAnt.

Be sure to look at the blog posts mirrored at the bottom of the project home page.

BTW: I agree with Jon Skeet on console apps. They can be useful, but if you have a tool like TestDriven.Net for VS.2005 and earlier, or the VS.2008 testing tools, you can step into your test code without creating your own harness app.

Gary.Ray
It works and it is smarter than me !!! ; ) Have to play with it for a while ... and add the log4net debuggging also ...
YordanGeorgiev