Welcome to Atalasoft Community Sign in | Help

Introduction:

The Message Passing interface (MPI) provides a standard way to distribute functions/objects/data across a cluster of systems -- whether embarrassingly parallel, or something more robust.  It’s an amazingly simple api to get started with, though working out how to send and receive the messages in the right order can get a bit tricky.  It only takes 6 commands to get going:

 

MPI::Init(argc , argv)

MPI::COMM_WORLD.Get_size()

MPI::COMM_WORLLD.Get_rank()

MPI::COMM_WORLD.Send()

MPI::COM_WORLD.Recv()

MPI::Finalize()

 

The way it works is every bit of code that is in between the MPI::Init(), and MPI::Finalize() gets executed across your cluster of systems whether they be a bunch of PCs,  a cluster of Tesla™ C1060s , or your BlueGene®/L  installation.  MPI just uses TCP to pass messages via MPI::COMM_WORLD.Send(), and MPI::COMM_WORLD.Recv() around to nodes in the cluster.  From the MPI.Net C# tutorial,

 “Unlike multi-threading, where different threads share the same program state, each of the MPI processes has its own, local program state that cannot be observed or modified by any other process except in response to a message. Therefore, the MPI processes themselves can be as distributed as the network permits, with different processes running on different machines or even different architectures.”  (pg3, MPI.Net C# Tutorial)

A Quick Example:

Provided you’ve got an MPI cluster working (try here, or here for a .Net version for setup instructions) you can run the “Hello World” of MPI:

#include “mpi.h”

#include <stdio.h>

#include <cstdlib>

 

 

int main(int argc, char *argv[]){

 

int nProcs, iMyProc;

MPI::Init( argc, argv );

nProcs = MPI::COMM_WORLD.Get_size();

iMyProc = MPI::COMM_WORLD.Get_rank();

cout << “Hello from process ”;

cout << iMyProc << “ of ”;

cout << nProcs << endl;

MPI::Finalize();

}

 

There’s no instructions being passed explicitly by the little chunk of code above, so there’s no need for calling either of MPI::COMM_WORLD.Send(), or MPI::COMM_WORLD.Recv(), but sending and receiving messages to nodes, or groups of nodes in your cluster is… well, really the whole point of it all, and the Send(), and Recv() calls are how you do it. 

Why would you care at all?

The computing world is getting parallel in a big way (thank you, Google) .  You don’t have to be particularly observant to have noticed this, but it is absolutely true.  MPI has been around for quite awhile, was created by the national labs to run their clusters, and is still used for that purpose specifically to deal with the problem of running multiple program functions across multiple systems on the same data – or different data.  That’s all well and good you say, but I’m not a national lab, so what should I use it for.  My plan is to use it to distribute tests to run across the cluster of Atalasoft engineer’s desktop systems to speed up UI tests, and to create some real load (stay tuned here to see how that adventure goes). 

 

Other Good Links:

Richard Edgar’s introduction to MPI:

http://www.cs264.org/files/IntroMPI.pdf

MPI (the spec):

http://www.mcs.anl.gov/research/projects/mpi/

MPICH2 (good open source implementation):

http://www.mcs.anl.gov/research/projects/mpich2/index.php

MPI.Net:

http://www.osl.iu.edu/research/mpi.net/


A recent series of tweets with @cemerick (follow me here)   got me to think about something that I’ve just taken for granted as something that is just done before every check-in (by at least two developers I know) – that being static analysis. It has seemed to me that most folks' (including mine) first impression of the massive amounts of output that a static analysis tool generates is, “Oh, dear Lord. What's all this crap about code style?”, and “Where're the useful results?”. After using it for a bit I came to appreciate it as a set of pragmatic heuristics providing a middle ground between formal system specification, and just getting it to compile.



What's it good for?

Good for teaching new folk.

Have a new developer that's never used the language before? Making them adjust to all of the warnings and errors that a static analysis tool generates will get them following what is probably generally accepted as “the way”. I'll give you a list of steps that you should go through before even thinking something is “ready” for whatever you might have in mind (you know check-in, review, etc...) that goes farther then just getting it to compile.

Lays a foundation for more advanced prediction systems.

There's a lot of current research on building defect prediction systems, and addressing the problem of people just ignoring the copious output generated, and putting it to good use. For examples see (sorry you will need an ACM account), http://portal.acm.org/citation.cfm?id=1062558, http://portal.acm.org/citation.cfm?id=1273487, (you'll need a IEEE account for this one) http://www2.computer.org/portal/web/csdl/doi/10.1109/TSE.2008.35. It's wouldn't be too hard to build a tool that does this since most of the analysis that is done has available open source implementations ready to be exploited. numpy, and openbayes are two I've been playing around with that have MCMC, PCA, and belief network modules ready to go.

You can modify it to your needs.

If you're still not happy with what the analysis is telling you you can always tweak it. Add your own rules, or stop the tool from reporting certain types of issues you don't care about or are convinced everyone follows anyways (yeah, sure they do).  It is usually just as simple as checking or unchecking a checkbox.



A list of static analysis tools I've played with:

Java:

findbugs -- http://findbugs.sourceforge.net/

agitarone -- http://www.agitar.com/ (Does have a evaluation period though)

C/C++:

Lint – Dudes, its everywhere.

Prefast – http://msdn.microsoft.com/en-us/library/ms933794.aspx

.Net:

fxCop – http://msdn.microsoft.com/en-us/library/bb429476%28VS.80%29.aspx

Python:

pyLint – http://pydev.sourceforge.net/pylint.html

BLOCKED SCRIPT

jsLint – http://www.jslint.com/lint.html


There are four opensource frameworks that I'm going to compare here Selenium, YUI Test, jsUnit, and WatiN.  There are many others available to use, but these four are the ones that fit in best with the developer workflow here at Atalasoft. There are only two things that I think every web testing framework should always do, 

          1.  Not inject anything into the AUT's (Application Under Test) DOM.

          2.  Have something like a WaitForLoaded() method.

For the four frameworks, I'm not going to go into how to use them, or how to set up your environment  to use them, or even a recommendation of which one I think you should use, just a presentation of my perceived pro's, and cons of each framework.

 JsUnit:

Pros:

Cons:

Similar api to well known “x”Units we’re all familiar with.

Documentation is only sufficient.

Has good test result logging.

Doesn’t integrate easily with nUnit.

Doesn’t inject itself into the application under test’s DOM.

Doesn’t integrate easily with CruiseControl for test result reporting.

Is just written in javascript.

Doesn’t have a WaitUntilLoaded() like method.

Is actively being developed.

Not easily distributed across many clients.

Runs in any browser that supports java script.

No test recorder.

Is fast (most of the time).

 

 

WatiN:

Every test is just written in C#.

Doesn’t have great support for Firefox.

Is runable in nUnit.

No support for Opera, or Safari.

Well, documentaed API.

Is slow.

Supports all of the latest .Net features (linq, lambda expressions, etc…).

Is not easily distributable to many clients for parallel testing.

Has great IE support.

 

Doesn’t inject it self into the  application under test’s DOM.

 

Has a WaitForComplete() method.

 

Actively being developed.

 

Reporting test results can be easily integrated through CruiseControl via the well known nUnit results.

 

Has a easy to use test recorder.

 

 

YUI Test:

Awesome documentation.

Injects itself into the AUT’s DOM

Works anywhere YUI works.

Doesn’t have a WaitUntilLoaded like method.

Comes with YUI.

Comes with YUI.

Is fast.

Is not easily distributed to clients for parallel testing.

Is just a javascript API.

Doesn’t easily report test outcomes through CruiseControl.

API ultimately controlled by Yahoo, and not community.

API ultimately controlled by Yahoo, and not community.

 

No test recorder.

 Selenium:

Run by the community, but is now heavily supported by google.

Documentation is scattered.

Expansive browser support.

Can be complicated to set up

Comes in a stand alone, remote control, and grid flavor.

Development efforts have stalled in the past.

Has an easy to use recorder for Firefox only.

Can be slow.

Doesn’t inject itself into the AUT’s DOM.

 

Has a WaitUntilLoaded() method

 

Can be fast.

 

Has a .net compiled C# version ready for nUnit.   For that matter, it supports all “x”Units currently available.

 

Has an easy to use html based scripting language.

 

Is distributable, and can run tests in parallel.

 

 

In the last throws of a testing sprint I started to go through my check list for all of the Atalasoft web components in IE (browser versions had been divied up for testing, and I got IE).  Not too long ago I read an article about IE's developer toolbar, at the time I thought "Oh, good. I can debug in IE now too -- sweet!" All had been going along fine now till now.  After the latest version in the web controls had been added I started to see the following exception when run in IE,

 

Microsoft JScript runtime error: Object doesn't support this property or method

 

when it hits this function,

 function ParseDoc(doc)
    {
        var aRules = GatherRulesFromDoc(doc);
        collSelectors = parser.Parse(aRules);
        
        // Set quirks mode if necessary
        if("BackCompat" == doc.compatMode)
        {
            for(var i = 0; i < collSelectors.Count; i++)
            {
                collSelectors.item(i).SetQuirksMode(true);
            }
       }

  }

 

Which was popped up every time I ran any script associated with the web controls, and after a few pop ups annotations added to the image disappeared.  Given that this function is nowhere to be found in any of Atalasoft's web libraries a quick search on the error brought up this rather helpful post that pointed to the culprit -- IE Developer Toolbar.   You can also just disable it, as I did, as there is a perfectly good and safe debugging tool already available -- FireBug

 

Yes, debugging and testing tool do change the system, but good ones never destroy data.

Ben Bittrolff [The Financial Ninja] wrote a post that got me thinking about what it takes to be a relevant tester.  In it he points to the FT article that says, and I'm paraphrasing here, that incorrect Aaa ratings that had been assigned to those big mortgage re-insurers was caused by a bug in the software, and that Moody's management knew about it for at least a year. 

To quote [the Financial Ninja], "OMG. OMG." 

What could be going on here?  Are the managers are just looking for a scapegoat (Probably)?  It's real easy to blame QA for the failings of really important software when purposely not given the resources to do the job right just to cut a corner.  Then again, maybe QA was not doing all it could to be relevant? 

 
So, what does one have to do to be a continually relevant QA resource? I don't purport to have all the answers to this yet, but my guide has been Rex Black's "Critical Testing Processes", which is quite possibly the best book out there on managing the testing process. There are three directions in which the QA leader needs to look according to Black, Upward, Outward, and Inward.

Inward -- It all starts with addressing the basic needs of the testing team, and in Black's opinion, is where the focus should be.  Do you have the right people involved in testing (skill sets & head count).  The right infrastructure in place to do the testing.  That an appropriate amount of time was alloted to backfill unit tests not written, or that needed to be expanded, then to do all of the integration, and system testing on an "good enough" sized configuration space.  Making sure that you get the right information to pass upward, and outward about the testing process, and about the state of the product.

Outward -- All the sales and marketing folk need to know about what works well, and what doesn't.  delivering this information to the sales, and marketing teams, and learning how the sale is made, and what it is that potential customers are interested in is useful for shaping the testing process. 

 Upward -- Your boss, and your boss' boss.  Sitting down with them to figure out what management's requirements of the release are to make clear what the ship, or not ship line is.  Also, to figure out what pieces of information they're interested in coming out of the testing process.

Black, of course, go into much more detail with lots of examples.  Out suggestions I'd say I'm hitting 80% of them, so there definitely room to do more over time.   

 


 

 



  

Technorati Profile

Question: 

Wouldn't it be really nice if Atalasoft had a TWAIN device certification program?

Answer:

Sure would.

checkmark

Yep.  That's right.  Pretty soon we'll have a certification program in place for manufacturers of scanners, and other capture devices to certify their hardware  as "Plays Nice with Atalasoft Products"; although, the actual marketing message probably will be a bit more elegant than that. 

So, what is it that we're currently thinking that should be part of the certification?  This is what we've got so far all of which comes right out of the Atalasoft.DotTwain assembly,

Methods:  Acquire, BackgroundDetection, CanOpen, Close, Disable, Dispose, Enable, Finalize, GetConditionCode, GetSupportedBarCode, GetSupportedBitDepths, GetSupportedBrightnessValues, GetSupportedCapabilities, GetSupportedCompressionModules, GetSupportedContrastValues, GetSupportedImageFormats, GetSupportedJpegPixelTypes, GetSupportedJpegPixelQualityTypes, GetSupportedNativeResolutions, GetSupportedOverscanModes, GetSupportedPixelTypes, GetSupportedResolution, GetSupportedTransferMethods, GetSupportedUnitTypes, Open, LoadParameters, LoadXmlParameters, SaveParameters, SaveXmlParameters, ShowUserInterface

 Properties:  Alarms,  AutoBrightness, AutoDiscardBlankPages, AutomaticBorderDetection, AutomaticDeskew, AutomaticRotate, BarCode, Bitdepth, BitDepthReduction, Brightness, Compression, Contrast, Controller, CustomDataSupported, DeviceEvents, DisplayProgressIndicator, DocumentFeeder, Duplex, DuplexEnabled, EnableInterfaceOnly, FileFormat, FileSystem, Frame, FrameSize, InterfaceControllable, JpegPixelType, JpegQuality, LampState, Lastreturncode, MinimumHeight, MinimumWidth, NativeResolution, ModalAquire, Online, Overscan, PaperDetectable, PhysicalHeight, PhysicalWidth, PixelFlavor, PixelType, Resolution, State, ThreadingEnabled, Threshold, TransferCount, TransferMethod, Units, ReacquireAllowed

That's quite a bit, even with out getting into each of the details of each one of those methods or propeties, but before you can start, you need to find out what the attached device reports it can do.  I'm going to do this with DotTwain as it is very straightforward in a WinForm application.  

The first thing you need to do is find the attached device list for your system:

 

private void LoadDeviceNames()

{

     // Never assume that a system has any acquisition devices.

     if (!this.acquisition1.SystemHasTwain || this.acquisition1.Devices.Count == 0)          

           return;

     string defaultDevice = this.acquisition1.Devices.Default.Identity.ProductName;

     // Add a menu item for each device.

     foreach (Device dev in this.acquisition1.Devices)

     {

          if (dev.Identity.ProductName == defaultDevice)

          {

               this.device = dev;

         }

        this.comboBox1.Items.Add(dev.Identity.ProductName);

     }

     try

     {

     this.device.Open();

     TwainResolution res = this.device.Resolution;

     }

     catch (Exception ex)

     {

     MessageBox.Show("There was an exception trying to open the system      default device.\r\n" + ex.Message, "Default Device Failed");

     CertFailed();

     }

     finally

     {

     this.device.Close();

     }

}

 

In the WinForm app, I have a combobox (combobox1) that gets populated with the names of the attached TWAIN devices. When I select one of them, it fires the following bit of code:

 

 

private void button1_Click(object sender, EventArgs e)

{

     //Get the selected device's capabilities.

     string deviceName = this.comboBox1.SelectedItem.ToString();

     try

     {

          device = acquisition1.Devices.GetDevice(deviceName);

          device.Open();

          capabilities = device.GetSupportedCapabilities();

          CertPassed();

      }

 

     catch (Exception openingException)

     {

          string error = openingException.ToString();

          MessageBox.Show(error);

          CertFailed();

     }

     finally

     {

          device.Close();

     }

}

 

..Which doesn't do much yet, but is a start in comparing the list of supported capabilites reported by the device to the list of things that I think it should do; which is exactly what I'll write about next time.

A post on CRAp4dotNet is long over due -- my sincerest apologies for those of you that have been holding your breath. 

From last time I mentioned that one of the two hurdles to get this working for .Net was computing the code complexity.  There aren't any good existing open source, and free options out there in the tubes to do this so I had to code it up all on my own.  I took a bag of words approach, and decided to just parse the source files with regular expressions.  There's probably a better way to do this, but at least this way its pretty trivial to extend the complexity class to parse any language you might want... as long as you compile the complexity class in .Net -- for now anyways. 

 A quick review of what cyclomatic complexity for those that don't want to click through.

CC = E - N + p

Where E is the number of edges in the graph, N is the number of nodes (verticies) in the graph, and p is the number of connected components.  In the implementation of this you just end up counting decision points in the source.  So, every if, then, else, foreach, do, etc... you encounter you add 1 to the method's complexity value. 

The next thing that needs to be determined is the class' aggregate complexity.  To get this just divide the sum of each method's complexity value by the number of methods.

Here it is free to use under the MIT license,

/***

 

 * Copyright (c) 2008 Adam Scarborough

 

 * All rights reserved.

 

 *

 

 * Redistribution and use in source and binary forms, with or without

 

 * modification, are permitted provided that the following conditions

 

 * are met:

 

 * 1. Redistributions of source code must retain the above copyright

 

 *    notice, this list of conditions and the following disclaimer.

 

 * 2. Redistributions in binary form must reproduce the above copyright

 

 *    notice, this list of conditions and the following disclaimer in the

 

 *    documentation and/or other materials provided with the distribution.

 

 * 3. Neither the name of the copyright holders nor the names of its

 

 *    contributors may be used to endorse or promote products derived from

 

 *    this software without specific prior written permission.

 

 *

 

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

 

 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

 

 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

 

 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE

 

 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

 

 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

 

 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

 

 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

 

 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

 

 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF

 

 * THE POSSIBILITY OF SUCH DAMAGE.

 

 */

 

 

 

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Collections;

using System.Text.RegularExpressions;

 

 

 

namespace complexityTest

{

    class CyclomaticComplexity

    {

        public static decimal fileComplexity = 1;

        public static decimal methodCount = 0;

 

        public static void Complexity(string path)

        {

            try

            {

                if (path.EndsWith(".cs") || path.EndsWith(".cpp") || path.EndsWith(".c"))

                {

                    ComplexityCalculator(path);

                }

                else

                {

                    DirectoryParser(path);

                }

            }

            catch (Exception e)

            {

                Console.WriteLine("Path not found:  " + path);

                Console.WriteLine(e);

            }

        }

 

        private static void DirectoryParser(string projectDirectoryPath)

        {

            // Process the list of files found in the directory.

            string[] fileEntries = Directory.GetFiles(projectDirectoryPath);

            foreach (string fileName in fileEntries)

                ComplexityCalculator(fileName);

              

          

            // Recurse into subdirectories of this directory.

            string[] subdirectoryEntries = Directory.GetDirectories(projectDirectoryPath);

            foreach (string subdirectory in subdirectoryEntries)

                DirectoryParser(subdirectory);

        }

 

        private static decimal ComplexityCalculator(string fileName)

        {

           

            if (fileName.EndsWith(".cs") || fileName.EndsWith(".cpp") || fileName.EndsWith(".c"))

            {

                try

                {

                    using (StreamReader sourceCode = new StreamReader(fileName))

                    {

                        String linesOfSource = sourceCode.ReadToEnd();

                       

                        methodCount = methodCount + FindNumberOfMethodsInClasses(linesOfSource);

                        fileComplexity = fileComplexity + Counter(linesOfSource);

                        return fileComplexity;

                    }

                  

                }

                catch (Exception e)

                {

                    Console.WriteLine("There was an error reading the source file:  " + fileName);

                    Console.WriteLine(e);

                    return 0;

                }

            }

            else

            {

                Console.WriteLine("Unsupported file type:  " + fileName);

                return 0;

            }

        }

 

        

        private static decimal Counter(string theSourceFileTurnedIntoABigString)

        {

            decimal complexityCount = 0;

            String[] matchString = { "(if)(?(\\s)\\(|\\()", "else", "(&&)", "(\\|\\|)", "(foreach)",

                                       "(\\(for)", "(do)", "(while)", "(switch)", "(case)(?(\\s)\\(|\\()",

                                       "(try)(?(\\r\\n)\\{|\\{)", "(catch)(?(\\s)\\(|\\()", "(\\?\\:)",

                                       "(else if)(?(\\s)\\(|\\()" };

           

            foreach (string regexSelectorString in matchString)

            {

                Regex selector = new Regex(regexSelectorString);

                MatchCollection selectorMatch = selector.Matches(theSourceFileTurnedIntoABigString);

                complexityCount += selectorMatch.Count;

            }

           

            return complexityCount;

        }

    }

}

 

The next step is to add a couple of methods to compute the aggregate complexity.  For that there will need to be two methods added. One to find the number, and start/end locations of the classes, and one to count the methods in the classes.

Over the weekend I took time away from family to go geek out Microsoft style at Code Camp 9 in Waltham, MA. 

map-o-waltham 

The talks were pretty much all geared towards introductory business application development.  It certainly would be nice if Microsoft could convince more of the local academic community that they're funding research for to come and make an appearance like they did for remix07. 

I was also surprised that there was not a single talk on F#.  With all the hype I've been seeing on it over the past few months I would've expected to see one session about it, guess it hasn't come up on the big business application developer's radar yet -- guess I'll have to pony up, and give a talk next time.  

One thing that should be a no brainer at any conference -- wireless access.  Please make it available to everyone.  The only way I could get it was to ask a presenter to give me their key.  Which would be against the rules, and morally wrong.  So, no internet for us.    

 

That said, I would definitely go again. 

 

The talks I went to:

Day One --  

1.   Index Optimization and Performance Tuning --

     The crux of the talk was indexing speeds things up...  However in the discussion of when to normalize/denormalize it struck me through that it all might be best handled with a stochastic model. Looks like others have had the same idea some time ago.  A small bit of searching dug up 1 & 2 (you'll need a JSTOR account to read these).  

2.  Real World httpModules and httpHandlers --

     My original plan had been to go to ASP.Net performance, and optimization as load and performace testing here at Atalasoft is a big deal, but for what ever reason the speaker didn't show up.  I ended up at Chris Love's talk instead.  I generally liked his format, start with a simple example to show its basic stuff, start extending, make a few mistakes along the way to show pitfalls, then end it all with a useful example.  Well done indeed.

3. An introduction to game development with XNA --

    A complete Pong in 40 minutes.  Yep, you heard me.  Just about went out and bought an xbox 360 after it was all over with.  Not to mention that Chris Bowen is a great, informative, and enteraining speaker. 

 4. WPF means business II --

     Found out about a nice little dubugger for wpf apps called mole debugger.

5.  Object relational mapping with nHibernate --

     This brough back memories of last summer for me.  Spent three months writing a whole bunch of xml to connect all the data layers of this project I was working on.  But really, this is good stuff... Really... I mean it.

6.  Big data: Managing terabytes with MS sql server --

     Throw hardware at it, and you problems magically disappear.

Day Two --

1.  Building a state machine workflow --

     I was really hoping for some talk of formal methods here, but it ended up being all about MS workflow.  Which is kinda neat.

2.  TDD with testdriven and nUnit --  

    I was totally amazed that when the speaker asked "Who is agile, and uses test driven development?"  that the only three people in the room to raise their hands were from Atalasoft -- shocking stuff.  The talk was good though, but then again, he was certainly preaching to the choir.

2 Comments
Filed under:

Attachment(s): map-o-waltham.jpg

If you can't measure it, you can't make it better, right?  Lots of folks have talked about software metrics, just go and pick up a copy of technometrics, or head on over to Cem's site for links to prove it to your self.  The problem with most of them is that many of the existing tried , and "true" methods is that they're CRAZY hard to implement for small Agile companies, and in many cases will cause more harm than good.  That's where CRAP comes in (I leave it to the reader to research further).  It's a simple metric that looks at two things,

                        1. Cyclomatic code complexity

                        2. Code path coverage   

 

to come up with the "CRAP factor" of your code.  More unit tests lower the CRAP factor, and less complexity also lowers the CRAP factor.   What's nice about this is that it's really hard for all those smart developers to game as making the CRAP factor go down involves good things happening in the development process.
 

The only problem, for me, with all the CRAP'py goodness is that its all written in Java, and runs in eclipse -- which is great...  Except,  Atalasoft is 100% .Net, and Microsoft Gold partner to boot. So, all Java solutions are no good for me.

Looks like its time to starting porting.  For those interested in helping me out let me know, and I'll put everything up on CodePlex ahead of it mostly working. There are two big issues that need to be solved to port CRAP4j to .Net.  You need an assembly that can give you path coverage statistics, and code to calculate the cyclomatic complexity. 

 
The easier issue to start getting into was figuring what to use for calculating code coverage as CRAP4j uses Agitar's coverage library; which, does all sorts of nice wonderful things that I can't make use of in .Net.  I chose PartCover as it's i) open source, ii)  does path coverage and pretty much everything else nCover does, but is open source, iii) works with .Net -- is open source, and iv) others are using it as well, did i mention it was open source.  There are plenty of problems with PartCover as well most notably that it doesn't purport to support ASP.Net at least according to the the forums, and needs to be massaged a bit more to get the needed information out of it to make the code complexity class work.

 

Next Week:  What I did to PartCover to make it work...

 

 

 


 

The Western Mass. developer group held a talk last night with Rich Hickey the creator of Clojure.  A video will be is available on blip.tv soon, or so I'm told by Lou

 

Some of the highlights for me were,

  •            Tight integartion with java.  If it can be written in java, you can wirte in far less code in clojure.  If you prefer you can write it all in java, and still get all the immutable goodness.
  • Lisp like syntax.
  • it's novel use of persistent data structures (more on this later). 

My apologies for this being a bit off topic, but it was just so darn cool.

 

 

 

Hello there! 

 

"Insert Quality Here"  is meant to be a bit of a poke at the idea that quality software can just happen magically.  Sprinkle on a few QA engineers, and all problem will go away, right?  Not exactly.  It takes an incredible amount of infrastructure, a bit of time, and smart people to build quality software that people actually want to use.  

 

So, what this blog going to be about?  The guts of testing and quality here at Atalasoft, and the tales of the hale and hearty men and women in the testing pit.  I hope you'll find it as interesting as I do.  

 

Cheers,

Adam Scarborough

QA Lead

Atalasoft
 

0 Comments
Filed under: