Tuesday, April 14, 2015

Composing a new Yii-1.x Project

The first question that one is confronted with when using Yii, is how to start a new project . There are some official tutorials like Creating Your First Yii Application

The problem with this approach is you first need to download Yii Framework zip file and, then later, put it under version control. Ideally it is a third party component, so it should be installed as any other PHP library, preferable using Composer.

Normally, when you are using Composer, you would like to put all the packages installed by composer in "protected/vendor" directory. This directory structure is created when "yiic webapp <app name>" command. We can issue this command as we don't have Yii yet. So its a catch-22. How to solve it?

The solution is simple. we decide what the our web-app name should be before-hand. e.g. "app". Create a main project directory and make a file named composer.json with the following content, in that directory (GIST here)

{ "require":{ "yiisoft/yii":"1.1.16", "yiiext/migrate-command":"0.8.0" }, "config":{ "vendor-dir":"app/protected/vendor/" } }
Then, issue the following command to install Yii. (If you have not installed Composer, you can refer to this link)
php composer.phar install
Once Yii is installed, we can use the following command to generate the Yii web-app
./app/protected/vendor/bin/yiic webapp app
Make sure that name of the web-app is the same as in composer.json. (in our case "app") Yii will create all the directories and it will reside in "protected/vendor" directory, itself.
Its a good idea to add "app/protected/vendor" directory in version-control ignore list (.svnignore, .gitignore)
One more thing to do is to load protected/vendor/autoload.php. A good place to do it, is in the beginning of  "protected/config/main.php". Add the following line there
require_once( dirname(__FILE__) . '/../vendor/autoload.php');
This is how you compose a new Yii project.

Wednesday, August 1, 2012

Unit testing C++ code using WinUnit and HippoMocks in Visual Studio 2010

VS2010 gives good support for unit-testing C# code. With Moq, you are all set and ready to write testable code. Doing the same for C++ can be a challenge. There are a lot of unit-test frameworks (http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B) and you can also make a test-project in VS2010 in managed C++ to test native code (http://blogs.msdn.com/b/jsocha/archive/2010/11/19/writing-unit-tests-in-visual-studio-for-native-c.aspx). I initially chose to use VS2010 for unit testing as I would get code-coverage results. The next question was how would I do mocking?

You cannot go far in unit-testing without a good mocking support. I tried to use GoogleMock but I could not get it to work in VS2010. The mocking is also not that easy as in Moq, as you have to write a class for every class you want to mock. I decided to look for some other mocking framework and after reading and testing a lot of them, I finally decided on HippoMocks (http://www.hippomocks.com/wiki/index.php/Main_Page)

Advantages of HippoMocks are:

At this point, I have decided VS2010 testing system and HippoMocks. After much work, I came to know that HippoMocks does not work well with managed C++ code. Now I had two choices; One, choose another mocking framework that work with managed C++ code; Two, choose another test runner. There are a lot of test-runners available but the reason I wanted to use VS2010 testing system is that I can get code-coverage results. I decided to go for a new test-runner.My search led to WinUnit (http://winunit.codeplex.com/) which said that it can provide code-coverage results. I tried it out and it was perfect (almost). I was able to use HippoMocks and get code-coverage results right back in VS2010. The only shortcoming is that WinUnit relies on Visual Studio macros in which the complete path the WinUnit.exe is to be specified.

To run the project, you have to:

  • Open "Macro Explorer" (Alt+F8)
  • Edit WinUnit->_Variables

    • Change WinUnitPath, WinUnitIncludeDir and VSPerfToolsDir according to your environment
    • Save the file (If the file give "access denied", check if WinUnit.vsmacros is editable)
  • In Solution Navigator, Select SampleCppTestsWinUnit project
  • Make sure you active solution platform is "Win32" (Use Configuration manager, if required)
  • In Macro Explorer, run WinUnit->RunningTestsWithCodeCoverage->RunTestsInSelectedProjectWithCoverage

You would get the following result

Happy unit-testing in C++

How to add Moles to your C# project

Mocking frameworks normally do not allow you to mock static properties and methods. You can use the "Moles" to provide a mock implementation of these properties. "Moles" is a lightweight framework for test stubs and detours in .NET that is based on delegates. Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.

The example below refers to "MyName2" project, which can be downloaded from here. In this project, I will provide a mock implementation of "Name" property in "Program" class.

  • The first thing is to download and Install 64 bit version of moles from here
  • Add a reference to Microsoft.Moles.Framework assembly to the project, which is to be tested. (MyName2).
  • Add the following lines in Propeties\AssemblyInfo.cs of the main project. (MyName2)
      1. using Microsoft.Moles.Framework;
      2. [assembly: MoledType(typeof(MyName2.Program))]
  • Replace "MyName2.Program" with the class containing the static property/method that you want to mole
  • In the test project, (MyName2.Tests), right-click on the assembly that contain the class whose property you want to mole (MyName2) and click "Add Mole Assembly"

    • A file by the name of <AssemblyName>.moles will be added to your test project. (MyName2.moles)
  • Build the test project so that a mole assembly is added in reference. Its name will have ".Moles" appended to the names of the assembly that you molded. (MyName2.Moles)
  • In the C# file that you are writing unit-tests, add the following line

      1. using Microsoft.Moles.Framework;
  • In the test method you want to use mole, add the following line under [TestMethod]

      1. using Microsoft.Moles.Framework;
  • Use the moled type to provide a delegate to the static method/property (MProgram.NameGet) which will be called when a get is done on Program.Name.

The main link to Microsoft Moles is http://research.microsoft.com/en-us/projects/moles/

Blogger Labels: C#,Unit Testing,Moles

How to unit-test dialogs in an application

Dialogs are common in any windows application. Dialogs provide challenges for unit-testing, as unit-tests are meant to run without user intervention. This is not possible if a dialog box keeps on popping when you run the unit-tests.

One way to solve the problem is to add a Boolean variable to stop the dialog from popping. It is set to True by default, so that usually, we see the dialog. It is set to False during unit-testing. It will increase your code coverage (in my test project it increased the coverage from 55% to 77.50%). To get better and "think" coverage, it is necessary to mock the dialog using an interface class.

In the test project, I have created a FileDialogDemo project and its corresponding test-project named FileDialogDemo.Tests. FileDialogDemo opens the standard Windows "Open File" dialog and shows the selected file in a text-box. This project includes the "Boolean flag" approach to increase some coverage. As a comparison, I have added a TestableFileDialog and its corresponding TestableFileDialog.Tests projects that shows the changes to make the dialog testable.

To unit-test the dialog we have to do the following steps:

  • Create an interface that can be mocked (e.g. by using Moq). It should include the methods and properties that we would like to mock

    • We created a IOpenFileDialog class with FileName and ShowDialog() method
  • Create a wrapper class that implements the interface. It would create an object of original dialog and have "pass-through" methods/properties to this object

    • In the demo, its name is OpenFileDialogWrapper
  • In the ViewModel code that is calling the showing the dialog, we create another method that takes the interface object as parameter. This will contain all the functionality of show the dialog and processing the results.

    • In the demo, its internal void BrowseFile(IOpenFileDialog dialog)
  • The original method will call the method (added above) by passing the instance of the wrapper class.
  • In the unit-test, we test the method that take the interface and pass a mocked version to simulate user behavior (like pressing OK or Cancel)

A comparison of code changes is as follows

 

Before

  1. public void BrowseFile()
  2. {
  3.     if (AllowShowDialog)
  4.     {
  5.         using (var dialog = new OpenFileDialog())
  6.         {
  7.             if (dialog.ShowDialog() == DialogResult.OK)
  8.             {
  9.                 FilePath = dialog.FileName;
  10.             }
  11.         }
  12.     }
  13. }

After

  1. public void BrowseFile()
  2. {
  3.     using (var dialog = new OpenFileDialogWrapper())
  4.     {
  5.         BrowseFile(dialog);
  6.     }
  7. }
  8.  
  9. internal void BrowseFile(IOpenFileDialog dialog)
  10. {
  11.     if (AllowShowDialog)
  12.     {
  13.         if (dialog.ShowDialog() == DialogResult.OK)
  14.         {
  15.             FilePath = dialog.FileName;
  16.         }
  17.     }
  18. }

 

The code coverage results show that now the coverage is 100% for the ViewModel.