Sunday, June 24, 2012

Running UI tests on local asp.net website with development server


These past couple of days I started writing a utility program that will invoke some UI tests against a certain website of my choice. Obviously, I needed to write tests for the functionality of this utility, so I will be sure that it works.
I wanted the tests to be as real as possible, and so I decided to run them against a real site, like google (could've been any other site, this doesn't really matter for the sake of the story).

The tests worked great, but then I realized that they could easily be broken, with no connection to my work - No one promises me that google's page structure (or anything I want to test) will always stay the same, and I don't even know which tests i'll want to add to it in the future, and if I'll have all the resources on the site of my choice.

I decided that I'll create a custom asp.net mvc site for the sake of my tests.
At first I configured the site on IIS locally and this was great, but then I started thinking another step forward, and realized I have another problem - I want someone else to be able to download the source code, and run the tests immediately without having to create a local website and going through all the proper configurations.

I realized that I could use the asp.net development server for this.
First, I needed to give the site a static port to run on in the development server :
(In the project properties page, go to the 'Web' tab, and mark 'Use Visual Studio Development Server' -> 'Specific Port')

Then, I created a class called 'DevelopmentServer' responsible for loading the asp.net development server, and shutting it down at the end :
public class DevelopmentServer : IDisposable
{
    private readonly Process _devServer;

    public static int Port = 1212;
    private string _devServerExe = @"C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE";
    private string _testSitePath = @"C:\Dev\MySitePath\";

    public DevelopmentServer()
    {
        _devServer = new Process {
            StartInfo = { 
                FileName = _devServerExe,
                Arguments = string.Format("/port:{0} /path:{1}", Port, _testSitePath)
            }
        };

        try
        {
            _devServer.Start();
        }
        catch
        {
            Console.WriteLine("Unable to start development server");
            throw;
        }
    }

    public void Dispose()
    {
        _devServer.Kill();
        _devServer.Dispose();
    }
}
The port number and the library paths are just hard coded for the sake of the example. It makes more sense to put them in some configuration file of your choice.
(Note: You might have to change the path to the file WebDev.WebServer40.exe which is the binary of the development server, according to the version you have. The earlier version of this file is called WebDev.WebServer20.exe)

Finally, I just created an instance of this class upon FixtureSetUp, and disposed of it on FixtureTearDown.

Thursday, June 21, 2012

Redirecting external Process output to Console.Writeline (or elsewhere)


As part of some code I was writing recently, At some point my app needed to trigger some other command line utility. I did this easily, using the Process class like this :
var myProcess = new Process {
    StartInfo = {
        FileName = "C:\\path\\to\\my\\cmd\\utility.exe",
        Arguments = " --some --random --args"
    }
};
myProcess.Start();

This was working great, with one exception - Sometimes the process was throwing an error, causing the console window to close immediately, and I didn't have time to view this error.
I knew that you can tell there was an error by the process's exit code (myProcess.ExitCode), but while debugging it was important to know what error was happening and actually see the output of this process.

Digging a little into the Process class, I easily found that you can redirect the process's output elsewhere. You just need to add :
// This needs to be set to false, in order to actually redirect the standard shell output
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;

// This is the event that is triggered when output data is received.
// I changed this to Console.WriteLine() - you can use whatever you want basically...
myProcess.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);

myProcess.Start();

myProcess.BeginOutputReadLine(); // without this, the OutputDataReceived event won't ever be triggered

That's it! Now i was getting all I needed from the running process, and it was much easier to find the problem this way. :)

Enjoy :)

Saturday, June 16, 2012

Having fun web crawling with phantomJs


A couple of weeks ago, a colleague of mine showed me this cool tool called phantomJs.
This is a headless browser, that can receive javascript to do almost anything you would want from a regular browser, just without rendering anything to the screen.

This could be really useful for tasks like running ui tests on a project you created, or crawling a set of web pages looking for something.

...So, this is exactly what i did!
There's a great site I know of that has a ton of great ebooks ready to download, but the problem is that they show you only 2 results on each page, and the search never finds anything!

Realizing that this site has a very simple url structure (e.g.: website/page/#), I just created a quick javascript file, telling phantomjs to go through the first 50 pages and search for a list of keywords that interest me. If i find something interesting, it saves the name of the book along with the page link into a text file so i can download them all later. :)

Here's the script :
var page;
var fs = require('fs');
var pageCount = 0;

scanPage(pageCount);

function scanPage(pageIndex) {
 // dispose of page before moving on
 if (typeof page !== 'undefined')
  page.release();

 // dispose of phantomjs if we're done
 if (pageIndex > 50) {
  phantom.exit();
  return;
 }

 pageIndex++;
 
 // start crawling...
 page = require('webpage').create();
 var currentPage = 'your-favorite-ebook-site-goes-here/page/' + pageIndex;
 page.open(currentPage, function(status) {
  if (status === 'success') {
   window.setTimeout(function() {
    console.log('crawling page ' + pageIndex);
    
    var booksNames = page.evaluate(function() {
     // there are 2 book titles on each page, just put these in an array
     return [ $($('h2 a')[0]).attr('title'), $($('h2 a')[1]).attr('title') ];
    });
    checkBookName(booksNames[0], currentPage);
    checkBookName(booksNames[1], currentPage);
    
    scanPage(pageIndex);
   }, 3000);
  }
  else {
   console.log('error crawling page ' + pageIndex);
   page.release();
  }
 });
}

// checks for interesting keywords in the book title,
// and saves the link for us if necessary
function checkBookName(bookTitle, bookLink) {
 var interestingKeywords = ['C#','java','nhibernate','windsor','ioc','dependency injection',
  'inversion of control','mysql'];
 for (var i=0; i<interestingKeywords.length; i++) {
  if (bookTitle.toLowerCase().indexOf(interestingKeywords[i]) !== -1) {
   // save the book title and link
   var a = bookTitle + ' => ' + bookLink + ';';
   fs.write('books.txt', a, 'a');
   console.log(a);
   break;
  }
 }
}

And this is what the script looks like, when running :
Just some notes on the script :
  • I added comments to try to make it as clear as possible. Feel free to contact me if it isn't.
  • I hid the real website name from the script for obvious reasons. This technique could be useful for a variety of things, but you should check first about legality issues.
  • I also added an interval of 3 seconds between each website crawl. Another precaution from putting too much load on their site.

In order to use this script, or something like it, just go to the phantomjs homepage, download it, and run this at the command line :
C:\your-phantomjs-lib\phantomjs your-script.js

Enjoy! :)

Friday, June 8, 2012

My opinion on GIT vs. SVN


I finally decided to convert to git...
Yes, this sounds like a religious statement (just like saying "i'm converting to christianity, judaism or islam") because it is!

Let me give some background -
At my work, we have a main svn repository, and we used to all use subversion (with Tortoise SVN and ankhSvn for VS compatibility). This was all great, until one day, some people decided that git is so much better than svn and they started convincing the others to try it out. So some of us did (or more accurately, attempted to try it out) by installing git extensions. In case you're not familiar, git extensions is a windows gui for git that is extendable so there's a plugin called git-svn that allows you to work git-based while actually having a svn server in the background. I went along and did just the same a couple of weeks ago. I also hosted a personal project on github to get the feeling of working with a real git repository (and not just using git-svn).

I must say, that working with git, is great!
...But also working with svn was great!
If i try to look back on it, I don't really remember the same people that are fans of git complaining about using svn the way they "claim" to have been complaining about it now. I think their more in love with the "coolness" of using git, since it seems like the cooler trend now-a-days.
Github has become so popular lately, and not for nothing - Their website is really easy and comfortable to use, and they have great tools for socializing and communicating on distributed projects over the internet. With that said, if they were hosting svn as well, I don't think it would be that big a difference.

All in all, git is great, but has it's share of problems. Svn has it's totally different share of problems as well. If there's a really good reason for me convincing you to start using git, it's because I truly believe that great developers should be well aware of the advantages and disadvantages each tool set gives you and that it's always good learning to use a new tool every once in a while. That's the only way to make the decision on which tools are best for you or your project.

Git and SVN are completely different in how they work, and it's really interesting to dig deep in to..
Here's a great post I read a while ago, that explains it really good : Understanding Distributed Version Control Systems

Monday, May 28, 2012

Sears Israel - Upcoming Hackathon...


A year ago, which was before I starting work at Sears, they had a 2-day 'dojo'. Everyone in the company grouped into teams and worked on projects that interested them the most. These projects weren't necessarily connected to what we do as a company, but just projects that we want to do for fun, and some of them are actually being used by people in the company till this day!
Until this day I am still hearing about how much fun it was, and how people are waiting for another event like the dojo.

The time has finally come, and in about a month we are having another event just like this. This time it is a 4 day hackathon, which is supposed to be about building applications on top of our platform for our site (www.shopyourway.com) or about building internal tools that will help us in the process of creation in the future. We are already talking about how we're going to build the teams and what apps we're going to build and all the buzz around the event is really exciting... I love it when we have a chance to express ourselves in a little more freely manner then usual, and I think this is essential in developing the people you work with in so many ways! :)

I thought I'd just post here some articles about different hackathons in some other cool companies around the globe :
- Facebook's hackathon page
- Twitter hack week
- Feedburner's hackathon
- Dropbox hack week
- Google's 20 percent time (which is basically like an ongoing hackathon)

You see... all the cool kids on the block are having them, so now it's our turn too!... :)

A big thank you to all the people running my workplace!!

You can be sure I'll update my blog after the event, and tell you about the project I worked on...

Thursday, April 26, 2012

Solving the "Move the Box" game (Programatically)


A couple of weeks ago some colleagues at work showed me this nice puzzle game called "Move the Box". I've seen dozens of these kinds of puzzle games in different variations, and as usual, I got hooked on it for a while.

I got stuck on a level I couldn't pass a couple of days ago, and this got my programming head thinking...
Hmmm... The board is only 6 by 7 tiles, and the levels only have up to 3 moves maximum... This shouldn't take too long for my computer to brute force through all the levels... :)

So, I got to work, and pretty easily got it solving the puzzles.
It works good on the puzzles i tested it on, which include puzzles with 1, 2 and 3 possible moves to the solution. The annoying part is that you have to enter the whole map of the level you want in a two dimensional array, which can take a long time. Then, all you have to do is tell it how many moves it gets, and hit F5!

Here's a screenshot of what I see when the code solves my puzzle -
Spoiler - This is the solution to the level "Osaka 22"

I put the code up on google code's project hosting if you wanna take a look, but this should come with a disclaimer -
The code is really ugly and hacky! This is only because it is a 'coding for fun' project at home, for something that will never reach any kind of production. The only thing that was important to me at the time coding this was the fact that it will work. I don't see myself using this ever again.
With that said, the logic of the board was still coded using classic TDD. It just seemed logical doing it that way, so it even has some cool tests.

http://code.google.com/p/move-the-box-solution/

...and if you're wondering, the answer is "yes" - This was a stupid idea, since I basically took all the fun out of playing this game for me! :)


Enjoy :)

Tuesday, April 17, 2012

Am I a good enough programmer ?

Ever since I started programming, this question has been bugging me. Now, I am trying to reflect on it from a different angle and I'm trying to understand what this even means to me and if in fact I am a "good enough programmer".

One of the most important things I learned a couple of years ago (from my team leader at the time), was that you can't define a goal without having a well-defined system to measure the success of reaching it. So, I must first define what being 'good enough' means to me.
In order to do that, I need to go back to the beginning...

The beginning
I started programming when I was about 12 years old (around the year 2000). It was building small applications for my first PC in Visual Basic for a short period, and about a year after that I started building websites using PHP and MySQL. Back in the day, I remember myself learning a lot from some books I ordered from amazon and reading easy-to-understand tutorials on the internet. I think at the time I was pretty much a script kiddie. A lot of the sites I built were from tutorials on the internet, and when I ran into problems I would run straight to the internet forums and wait for someone to help me out. I looked up to the ones in the forums answering my questions and publishing all the open source javascript/php components I was using freely, when sometimes I didn't even understand how they worked.
What I remember clearly from that period was wanting to be as good as those 'guys' on the internet - the ones answering my questions and publishing open source. I wanted to be another success story like the guys from Mirabilis or other companies at the time I was reading about during the dot-com bubble period.

Getting better
After a while, I felt like I had a lot of knowledge about PHP and MySQL (boy, was I wrong at the time), and I started building ecommerce websites as a freelancer. I built some nice websites (which some of are running till this date without any need of maintenance) and I felt like I was on top of the world. I was just waiting to finish high-school and make a career out of my favorite hobby!

Working on a team
After high school I served in the Air Force (mandatory in Israel) for 3 and a half years, 2 of those years as a computer programmer. This was the first time working on a team with other developers. Some of these developers had fancy college degrees and some of them had a couple more years of experience than I did. This blew my mind away! All of a sudden I felt like I met a new species of programmers I didn't know before. It seemed like these guys didn't only know how to program but they had a deep sense of knowledge of what their code means and how it was affecting the CPU. They all had their own blogs and every week one of them would present a lecture, talking about something new and teaching the team about new technologies.
I was totally blown away by this, and this convinced me that I wasn't even close to where I wanna be as a programmer...

Getting even better
I started reading a shit load of programming books, subscribing to some blogs on the internet and started diving into some leading open source code projects that were popular at the time. I even started a blog on my own as a way of learning more myself. During this period I learned so much and looking back at it, I would've never reached the amount of knowledge I know today without working with other people better than me (just a side note to others). By the end of those two years, I even managed to do some lectures myself and I think in some of them I got to teach others something new.

The 'real' world
My first 'real' job was working for an Israeli credit card company. At first I felt intimidated by this, since I didn't know if I gained enough experience to be working in a big company, so I continued doing what I learned to do. Learn, learn and learn! I continued reading a lot of blogs and learning as much as I can, so I can be as good as the best at my current workplace. That didn't take long and I became one of the best there. I soon became bored and started looking for a new job...
I interviewed at a couple of places but only had a connection with one of them. (I wrote about this in a previous post : A new direction) This is Sears Israel (SHC), which has been my current workplace for the past 6-7 months. Not surprisingly, here I met programmers that are even better than I ever met before, and immediately wanted to go in their footsteps.

I could go on about how I continued learning as much as I can, but I think you get the point (and looking back at how much I wrote, I doubt anyone would read this whole post!)...
So now I look back at that feeling I had when I first started out programming, not knowing how good I wanted to be, just knowing I want to be better, and I think today I can say that I feel almost the same way. A couple of times already, I tried to define goals as to 'how good' I want to be, but these definitions never hold, since there are always new technologies out there to conquer and more programming languages to learn. The second I feel like I reached that point, I just find something new I want to learn and think I'm not good enough since I don't know that yet...
This is probably one of the reasons I am still in this field of work. The challenges are never over, and your work is never complete.

Today, I can appreciate the fact that I know that I am working amongst some of the more talented programmers in Israel.
I know I'm not the best, but I am still striving to get there! I still don't know what being the best means, and if I'll ever get there, but I do know that I'm enjoying the whole process. I know as a fact I am getting better all the time and I know that just the fact of wanting to be better and doing something about it makes me better than most.

I know I am a whole lot better than I used to be just a couple of years ago, and I'm pretty sure that in a couple of years from today I will be able to say the same again. This thought gives me some peace :) and is VERY satisfying by itself!

Part of the reason I am writing this post is to be a message to myself and to others - You are not the best (this goes for 99.99% of potential readers), but (and this is a big 'but') you should always strive to be the best. Keep reading, learning and programming as much as you can and maybe one day you will be. Doing this will keep you in a good position and on the way to getting there.