Sunday, September 23, 2012

Home debugging, part 2: can't create a new user account on windows 7, 'the user profile service service failed the logon'.



The next home network maintenance task took a little longer to solve. My mother wanted to create her own user account on the shared PC. She knew how to do this, but the new account kept giving an error when she tried to log on with it: 'the user profile service service failed the logon'. Cryptic.

It sounded easy. I was confident that I'd solve it in minutes. I googled it, and found several recommendations to delete the corrupt user profile/reg key and boom. But why would the newly created profile be corrupt? Turns out, it's not: it's not even created until you log on with it for the first time. So there was no profile to delete.

I tried turning off UAC, and creating a new account with admin rights instead of standard, but none of this worked. Eventually, I found this Microsoft Answers thread: http://answers.microsoft.com/en-us/windows/forum/windows_7-security/i-cannot-create-a-new-user-account-windows-7-the/dee340f7-5da9-402b-9e99-293dbd249a53?page=2 which pinpointed the problem as an access failure while copying data to the new user profile. I felt a little silly for not thinking to look through the event logs earlier in the process, but here is the step by step guide to fixing this error if you're having the same problem:

- open the Event Viewer (Start->Run->type "Event Viewer") and look at the Application logs


-  Now find any Warnings (the Error messages are likely telling you that the user profile didn't work, which you already know) and click on each of them to read the details about it

 
 
 
- You should be able to find a warning message that says 'Windows cannot copy file x to location C:\Users\Temp...' 
 
- Find the file mentioned by typing in the full directory location given to the address bar of Windows Explorer. (You can't browse to it because it will be hidden). 
 
WARNING: deleting or changing some files will break your computer. If you don't know what the file mentioned is, you should find someone who knows more than you do.
 
- If you know what you are doing, now go ahead and delete or give universal write access on the file. Et voila, your new user account should log on successfully.

Home debugging, part 1: hacked wifi?

And now for something completely different!

I'm at home in Australia for a few weeks* visiting my parents, so obviously I've been doing a little home PC maintenance. Between my dad, sister and brother they are able to pretty well manage everything, so it hasn't been too bad.

My most stunning accomplishment has been setting up a Windows Homegroup so that they can all send documents to the printer from their laptops and the second desktop, instead of kicking off anyone currently using the PC with the printer for a minute.

More interestingly, a couple months ago, my sister rang me early in the morning to say that she thought the wifi had been hacked. I rolled my eyes and asked what was happening, and she said that overnight, all the phones (which get carried in and out of the house, and therefore off the wireless network) had stopped connecting to the local wifi and said the password was incorrect. The laptops which had stayed in the house were still connected, but the laptop that had left the house that day was also unable to connect. When I directed her to the router admin page, which according to Dad's notes still had the default password, she was unable to log in. It appeared that she was right, and someone had indeed managed to change the password on their wifi network. I gave her instructions for resetting the router and setting the network back up, and left her to it.

Fast forward: I've been home for about a week. I'm testing some phone stuff on two different phones. As each phone sits idle, it disconnects from the wireless network, then seamlessly reconnects when I wake it up. Until one doesn't. It says the password is wrong. Then the other phone won't reconnect either. I go find my sisters iPhone and it also won't connect - password incorrect. (I have no interest in disconnecting my laptop to test it as well.) It appears that whatever happened before, has happened again.I go find my sister's documentation from that incident: she didn't change any of the passwords involved, including the router sitting on the default password. So yea, I guess it's not inconceivable that someone got into it again? I reset the router, set back up the network and the voip line, and this time change the router password.

I still find it a little unbelievable that someone would have gotten into their wireless network twice, in this random corner of the suburbs, but I can't come up with another explanation.


*Yes, it was incredibly inconvenient for my house to flood days before I left on an international trip. 

Conflicts and setbacks


So, ran into a few challenges recently.

I have mentioned that I work at Microsoft, but here it becomes relevant that I specifically work on the Windows Phone marketplace: the experience you have when you install an app as a user. As part of my job, I was involved in investigating and diagnosing <a href="http://windowsteamblog.com/windows_phone/b/windowsphone/archive/2012/08/14/can-t-download-an-app-here-s-why.aspx">the recent problem installing app updates</a>, and I also know the team involved in managing app certification, so I was well aware of the subsequent <a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2012/08/14/app-publishing-temporarily-on-hold.aspx">delays in app publishing</a>.

This was pretty inconvenient for me personally, as I submitted the PAX Digital Assistant update for Prime to the marketplace only the day before certification was temporarily halted. I waited for my app to make its way through certification once everything resumed, and kept waiting. I checked at work and knew there were major delays catching up with the queue of apps that had built up, and so it wasn't unbelievable that mine hadn't made it through yet. I knew that I could contact the guys who ran the process and have my app fast tracked, but I couldn't decide if that was reasonable or not. In hindsight, I think it would have been: I had a good justification with the event actually happening, and other developers do contact a developer evangelist for similar deadlines. However I decided that it felt a little unfair to use my internal position like that, so I didn't do anything, and my app didn't make it through publishing until September 6, well after the useful moment had passed. Now I feel like I inconvenienced a bunch of people and made myself look flaky and unreliable, all for no good reason. Damn.

On the worse side, four days before PAX my apartment was flooded by a burst pipe, and my laptop was destroyed. As detailed in my last post, I did have a remote backup for the PAX app - but I hadn't done incremental uploads to the server of the last couple days of work I'd done before finishing it for Prime, so that work is now gone forever. The Flashcard app I'd created is also completely gone, as I hadn't bothered backing it up to the server at all (not a huge loss, but a foolish mistake). Could have been worse, of course: a month earlier the entire PAX app was stored only on my local machine and would have been gone. But could have been better as well. I need to make the incremental backup to the server as easy as the local incremental backup.

Sunday, August 5, 2012

Success: a 7.1 app backed up on a remote server!


I've spent a bit of time now trying to get the upgraded 7.1 version working, however the app crashes on loading the schedule pivot page containing the jumplist.  I decided to try and put a plain list of the items in order to get a functioning 7.1 app - but  found that the crash wasn't caused by the telerik controls at all.

I tried to get the minimal list going with this:
        <controls:Pivot
           
 x:Name="schedulePivot"
           
 HeaderTemplate="{StaticResource pivotTitleTemplate}">
            <controls:PivotItem>
                <ListBox
                   
 ItemsSource="{Binding events}"
                   
 ItemTemplate="{StaticResource eventTemplate}">
                </ListBox>
            </controls:PivotItem> (line 64)
        </controls:Pivot>

I got this XAML parse error: AG_E_UNKNOWN_ERROR [Line: 64 Position: 34]


        <controls:Pivot
           
 x:Name="schedulePivot"
           
 HeaderTemplate="{StaticResource pivotTitleTemplate}">
            <controls:PivotItem>
                <TextBlock Text="hello" />
            </controls:PivotItem> (line 61)
        </controls:Pivot>

Gives me the same error on line 61, so it isn't about the lists at all.

It turns out I got this error as soon as I add any PivotItem to the pivot, even an empty one.

Ok...looked into the exception stack trace and it included this detail:


            at System.Windows.UIElement.UpdateLayout()
            at Microsoft.Phone.Controls.Pivot.OnItemsChanged(NotifyCollectionChangedEventArgs e)
            at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
            at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
            at System.Windows.Controls.ItemCollection.NotifyCollectionReady()
            at System.Windows.Controls.ItemsControl.NotifyAllItemsAdded(IntPtr nativeItemsControl)
            at MS.Internal.XcpImports.Application_LoadComponentNative(IntPtr pContext, IntPtr pComponent, UInt32 cUriStringLength, String uriString, UInt32 cXamlStrLength, Byte* pXamlStr, UInt32 cAssemblyStrLength, String assemblyStr)
            at MS.Internal.XcpImports.Application_LoadComponent(IManagedPeerBase componentAsDO, String resourceLocator, UnmanagedMemoryStream stream, UInt32 numBytesToRead, String assemblyString)
            at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
            at PAX7.View.SchedulePivotView.InitializeComponent()
            at PAX7.View.SchedulePivotView.OnNavigatedTo(NavigationEventArgs e)
            at Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedTo(NavigationEventArgs e)

So I thought perhaps the exception was something to do with the pivotitems I was creating not working with the data I'm assigning to it? I removed the PivotItems and set DataTemplates on the Pivot itself, like this:


        <controls:Pivot x:Name="schedulePivot"
                       
 HeaderTemplate="{StaticResource pivotTitleTemplate}"
                       
 ItemTemplate="{StaticResource pivotListTemplate}">
                        
        </controls:Pivot>

Referring to existing templates like this:
        <DataTemplate x:Key="pivotListTemplate">
            <ListBox
               
 ItemsSource="{Binding events}"
               
 ItemTemplate="{StaticResource eventTemplate}">
            </ListBox>
        </DataTemplate>

Magic! Finally I have a working app built on the 7.1 SDK :) Obviously I committed it straight away. Then I remembered that I hadn't got a backup on a separate machine yet, so I googled remote repository hg nearlyfreespeech, and found this awesome page:

Before sending it up to my new remote repository,  I thought I'd make sure it wasn't including all my generated files. I found a couple relevant Stack Overflow questions  (e.g. http://stackoverflow.com/questions/3426231/mercurial-hgignore-some-questions-on-how-to-ignore-a-single-file) that led me to the help page (http://www.selenic.com/mercurial/hgignore.5.html). Although when I look at 'all files' in the repository it doesn't list the bin/obj directories now, when I ran the clone it still did because it was looking at the history of the repository, which obviously still mentioned them.

Then cloning failed anyway with an 'invalid argument' error. Google told me there was a known issue with clone/push/pull of large filesets on windows? Lame! (http://mercurial.808500.n3.nabble.com/TortoiseHG-Large-File-Commit-only-40Meg-is-size-td2140178.html) 
So I tried creating a bundle of just the latest revision (http://tortoisehg.bitbucket.org/manual/0.9/changelog.html#revision-context-menus) and cloning it, but tortoise just went ahead and tried creating a stupid huge bundle again when I hit clone, instead of pulling from the bundle. So I turned on the server option, but couldn't figure out what the url should be - when I tried hg pull <url listed in serve ui> I got an error that the hostname wasn't recognised.
I uploaded the bundle I'd created through ssh, and tried pulling from it locally (inspired by http://weblogs.java.net/blog/kohsuke/archive/2007/08/mercurial_trans.html) but got an error that the parent wasn't recognised. However import/export also didn't work, saying it couldn't find files to patch. So I created a backup bundle as listed here (http://www.southampton.ac.uk/~fangohr/computing/hg.html#use-mercurial-without-access-to-server-using-bundles) and copied that to the server, pulled from that and finally had a repository. Done!

I think the whole rigmarole indicates that I don't have a strong enough grasp on how hg is supposed to work.  Let's see how it goes when I try and just copy over a changeset...

Saturday, July 21, 2012

Source control/backup and testing.

So for most of my projects I have a Mercurial repository for version control (totally saved my ass when I found a bug in the submitted version of Pax while halfway through unsuccessfully updating the code to 7.1), but no backup. I thought about setting up remote repositories (I have hosting with Nearly Free Speech), but I also remembered that GitHub had recently released their Windows client. I was unable to download/install the client over the coffeeshop wifi so had to set that up at home later - now you can see the code at https://github.com/jacalata/FlashCards. If that works nicely I'll put my Pax code up there as well.

I have created a test project for my Pax app in the past, but...a long time in the past. So I found this guide (http://blogs.msdn.com/b/amit_chatterjee/archive/2011/06/26/unit-testing-the-windows-phone-7-applications.aspx) as a reminder, and also found that the dll's I had were all 7.0 projects, so updated them. Added the first couple of unit tests, more to go.  Does feel better knowing I have a test framework though :)

Thursday, July 19, 2012

Flashcards app

I recently got the Telerik controls for Windows Phone (free in a deal for MS employees) and plan to use that to improve my Pax app - specifically I need the jumplist to replace the third party implementation I have now, which doesn't work for a 7.1 app. Before going in to replace everything in my Pax app, I thought I'd create a new app to get used to working with them.  

I have vague aspirations of doing a little more concentrated data structures and algorithms revision this year, and working on my french/icelandic, so I thought I could build myself a flashcard app. I used one of the Telerik default app options, which was nice and clean. I found the couple of controls I added quite simple to use: the basic info is all easily available at http://www.telerik.com/products/windows-phone/overview/all-controls.aspx,  but  I'd love that page to contain the dll each control is in, rather than looking through the 6 options. Or ideally to link to a page for each control with the full docs for it (I'm sure I found full docs, but I've forgotten where - I mostly worked by looking controls up in the Object Browser in VS). 

The first version of the app is super basic: one set of cards, can add/delete only, can move through sequentially or randomly. No option to enter the answer to keep yourself honest, no option to edit cards. What took the most time was creating the icon, which is still totally crap - all Paint no talent. Overall it took me two evenings, (probably about 8 hours) to get a working minimal version ready to submit to the app store. I didn't actually write any tests, which is bad. But it was pretty satisfying to get that done.  

I also set up a Trello board for the app (https://trello.com/board/flashcards-app/4ffb6ccacb4f94632522f9970), which I'm finding to be a really easy way to track projects. To keep myself honest, the next two tasks are tests and version control (I can't believe I forgot to do that).

Thursday, May 24, 2012

Upgrading to 7.1


I upgraded my app project to 7.1 back in late March, but it didn't go smoothly. 

Immediately after upgrading, I wanted to run the project and make sure upgrading hadn't broken anything. Unfortunately the first thing I got was a cryptic runtime Exception: 'WrappedException' with details 'Unspecified Error', breaking when I initialised a boolean for the first time. I googled the exception and found other people complaining that upgrading their projects gave them these errors as well - http://forums.create.msdn.com/forums/t/88547.aspx - the problem seemed to be running the old version of the Silverlight Toolkit or the CodingForFun toolkit. I have both of these, so time to upgrade them through nuget.
But...it turned out I have the most recent version? Crap. Try rebuilding from clean - didn't help. 

I searched again and found two articles both mentioning this error in relation to template bindings - http://www.wirebear.com/blog/2010/10/21/windows-phone-7-unspecified-error/ and http://www.telerik.com/community/forums/windows-phone/databound-listbox/unspecified-error-on-databoundlistbox-for-mango.aspx  so I guess I went through my project and checked the templates on that page.
  1. Commented out both the headertemplate and the jumplist itemtemplate - the app ran fine
  1. Put back in just the header template - app ran fine. So I guess it is /sigh/ somewhere within my horrible nested jumplist template.
  1. Just for fun, put them all back in - fails! The exception detail:

MS.Internal.WrappedException was unhandled
  Message=Unspecified error
  StackTrace:
       at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
       at MS.Internal.XcpImports.UIElement_UpdateLayout(UIElement element)
       at System.Windows.UIElement.UpdateLayout()
.....
 InnerException:
       Message=Unspecified error
       StackTrace:
            at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
            at MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element, Size availableSize)
            at System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize)
            at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement child, Size layoutSlotSize)
            at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)

 
And I've narrowed it down to this template:
  <DataTemplate x:Key="pivotJumplistTemplate">
            <l:JumpList
               
 ScrollDuration="400"
               
 ItemsSource="{Binding events}"
               
 ItemTemplate="{StaticResource eventTemplateByDay}"
               
 JumpButtonStyle="{StaticResource AccentColoredButtonStyle}">
                <l:JumpList.CategoryProvider>
                    <l:DistinctPropertyValueCategoryProvider PropertyName="StartTime"/>
                </l:JumpList.CategoryProvider>
            </l:JumpList>
        </DataTemplate>

If I replace this one with the non-jumplist, it works.

        <DataTemplate x:Key="pivotListTemplate">
            <ListBox
               
 ItemsSource="{Binding events}"
               
 ItemTemplate="{StaticResource eventTemplate}">
            </ListBox>
        </DataTemplate>

Aha - and now adding Jumplist to my search,  I get this article from the guy who wrote the control I'm using - 
All the comments say they are seeing this error. Turns out the control is now distributed as part of http://wp7contrib.codeplex.com/, which has been updated for 7.1. Installed the new package with nuget and swapped out my assembly references….and got the same exception.  And so were other people since September - I can't find an indication that he's updated it since then. I left a comment on the post asking if it had been updated. He's responded a couple of times since then saying he is planning to update, but hasn't had time recently.

Fortunately Telerik recently had a special for Microsoft employees, so I got their Windows Phone suite free - I can insert their jumplist instead.

Tuesday, March 6, 2012

extracting the hardcoded info


PAX East schedule is out! I need to get cracking on this. I also got another response to my app survey today, where the only feature requested is 'update for pax east'. 

So, last week I implemented the ability to download a hardcoded file from my server. Now I need to adapt that so that I can download whatever files are available, and that I only do this if they are updated from my version.  I want to add this option in an app bar, but I need the collapsed app bar which is only available in mango, and I'm hoping to get one last usable version for pax east out in pre-mango format. So I've added this button in the about page (terrible design, I know). I might also want to add a little notification to the front menu letting the user know if a new version is available?
I should add a 'what's new' popup on first run, like 4th and Mayor.

I wired up a button in the about screen to look for a new schedule on my server, and put a really lame 'version info' file on the server, looks like this
3.1.2012
"East/2012"

So this is - date = last time the server schedule was updated, and location= folder location to look in on the server. In that folder will be a zip file of all the xml files. Each zip needs to be a complete set - I'm not going to try and manage just sending the new events or anything like that. (I'm mostly being inspired here by this article on downloading and reading from a zip - http://www.galasoft.ch/mydotnet/articles/article-2008032301.html

I actually format the event schedule  into xml by hand. I copy the plain text from the official website, then
  1. Remove special characters - /&" are the main ones. Also odd quote chars like ’ and — and …
  2. Manually insert an 'Event' heading for each event
  3. arbitrarily decide on the 'type' of the event, basically I put as 'show' anything that doesn't sound like it'll have audience participation/questions. 
Etc etc

I've hardcoded lots of things that need changing. I haven't gotten a full plan for how to best handle this instead.
  1. Panorama title says' PAX Prime 2011' - updated
  1. Maps are all of Seattle - I have the bcec and boston maps, but will the pax specific ones change? I should probably wait here...nah, I'll almost definitely need to send out another update later. For now let's put in last year's maps.
  1. Useful links are seattle based - updated


public get, private set, public crash?


Goodness,  I seem to have found the weirdest bug. I decided to pull all the event headings into the Schedule class ("Manticore" etc) as a precursor to loading these dynamically from a settings file.  I set up the lists like this:

        
public List<string> eventDays
        {
            
get { return eventDays; }
            
private set { }
        }

However, all of a sudden I found that the app would completely and silently crash, not even throwing an exception for me, when it tried to access any of these list variables - even from within the same class. I removed the get/set so they were just public variables, and the app worked fine again. Then I put back this get/set code, and the app crash reliably reproduced, and then visual studio itself crashed.

    public Schedule()
        {
            
ObservableCollection<Event> events = new ObservableCollection<Event>();
            Events = events;
            eventDays = 
new List<string>();
        }

        private void readSchemaFile()
        {
            
if (eventLocations == null)
            {
                eventLocations = 
new List<String>();
            }
   //populate list
      }


edit: the next day, when it was not 2am, someone pointed out to me that I had obviously put a recursive get on eventDays, so it was crashing with a stack overflow. Way to go, me. 

xaml fiddling


Took a 2 day course at work that gave me a good overview of the changes available in mango, but was overall aimed at a new developer and probably not worth my entire two days. I did spend the time working on the app and updated the search to look and act like marketplace search on the device
  • Got rid of the separate search.xaml so that now it is presented in the schedulepivotview.xaml like any other view of events
  • Had to add a bunch of items to this (search header, search textbox, text to show if a view is empty) and found that if I put it all in a stackpanel, the list of events doesn't scroll (documented online in a couple of places - the list needs to be inside something with a set size, when it's in a stackpanel it thinks it has unlimited viewspace and so doesn’t need to scroll). However if I just put all the items in the top grid and hid the non-relevant ones, then the touch didn't seem to work on the pivot, presumably because other items were 'in the same place'. I worked around this by putting all the extra controls in a stackpanel that was collapsed by default, like this
  • <Grid>
    • <StackPanel>
      • <textblock search header>
      • <textbox search entry>
    • <Pivot>
    • <StackPanel>
      • <textblock empty search text>
      • <textblock empty 'my schedule' text>

  • As a bonus, this made it easy to also implement a notice when the user enters my schedule and has not yet added any items to it.

Also added an inline star to all items that are in your schedule, so you can tell without clicking on details whether you've already added this one.

Sunday, February 12, 2012

Implementing asynchronous testing

So when I had got my test project set up so it at least ran, I started creating a whole set of tests, most of which just do Assert.Inconclusive("Not yet implemented"). Now I'm going through and implementing them one by one.

Class - ScheduleViewModel contains a private instance of the class Schedule. When I call ScheduleViewModel.Load(), it calls Schedule.Load(), which fires an event on completion and then the method ScheduleViewModel.LoadingComplete() handles that event. Unfortunately,  without just making everything public (or internal, but that's not much cleaner) I can't make my test aware of this event, so that it can wait to assess the results of LoadingComplete()

So what I think I'm doing here, is changing the method ScheduleViewModel.LoadingComplete to catch the event from schedule, and throw another one that will be caught by a new ScheduleViewModel.LoadReallyComplete method. This new event will be visible to the test code, so we can wait on it.

 test method:
            _viewModel = new ScheduleViewModel(pivotView, pivotParam);
            Assert.IsNotNull(_viewModel);
 
             // make sure we wait for the ScheduleLoadingComplete to happen            
            _viewModel.VM_ScheduleLoadingComplete += 
                new EventHandler<ScheduleLoadingEventArgs>(ScheduleCallback);
            _viewModel.LoadSchedule();
            // wait for our method to trigger on the event and set this to true
            EnqueueConditional(() => _callbackDone);
 
            foreach (var slice in _viewModel.EventSlices)
            {
                Assert.IsNotNull(slice);
            }
 
        //event handler helper - triggered by the ScheduleLoading event in the ScheduleViewModel, sets _callbackDone to true
        public void ScheduleCallback(object sender, ScheduleLoadingEventArgs e)
        {
            _callbackDone = true;
        } 


class under test:
  public event EventHandler<ScheduleLoadingEventArgs> VM_ScheduleLoadingComplete;
 
        // this method will be called when the Schedule instance finishes loading. It will then throw its own event
        // that will trigger the LoadPopulatedSchedule() method  
        public void Schedule_ScheduleLoadingComplete(object sender, ScheduleLoadingEventArgs e)
        {
            // throw an event for finished loading
            if (VM_ScheduleLoadingComplete != null)
            {
                VM_ScheduleLoadingComplete(this, e);
            }
        }
 
        public void LoadPopulatedSchedule(object sender, ScheduleLoadingEventArgs e)
        {
//does a lot of stuff            // Fire Event on UI Thread
            view.Dispatcher.BeginInvoke(() =>
            {
                view.OnLoadComplete();
            });
        }



Now that I'd come this far, however, I realised that I actually want to fire my event for the test right at the end of LoadPopulatedSchedule, where I'm currently firing the UI event. So I could get rid of my 'trigger on one event, raise another' method, and add the new event to the end of LoadPopulatedSchedule, right after the UI Dispatcher invoke.(It seems like I should be able to make the test trigger on the UI event, but for now this seems close enough)

Of course, once I had everything triggering correctly on events, it turned out that I actually hadn't initialised the data structure correctly in the first place, and then that I was looking at the wrong set of results, and then that I wasn't correctly clearing my test data so that every subsequent test failed. And once I'd solved all them, I found that the UI method being dispatched was calling a method that referred to variables instantiated in the xaml, so were failing with null references when run under the test harness.


Reading material from this session:
basic stack overflow question
http://blogs.infosupport.com/unit-testing-with-silverlight/
http://www.codebadger.com/blog/post/2009/09/08/Unit-Testing-Silverlight-ViewModels-%28MVVM%29-That-Make-Asynchronous-Calls.aspx

Saturday, February 11, 2012

Beginning to test

For the first two releases, I had only manual tests. This was clearly inadequate - I want to make some major changes to the app, and it's going to be pretty annoying to have to go and walk through all the app functionality after each change. I test software for a living, and I strongly believe in testing early and often - I am in theory a fan of test driven development, but I totally fell over when it came to actually building a new project from scratch. Time to fix that.

I began looking into all the test frameworks available for Windows Phone apps. There are several, and I didn't really know which way was going to be 'best' or 'easiest'. I already had the Silverlight Toolkit installed, and was working in a theoretically MVVM framework, so I looked for approaches designed to work with that. I found (among many others) these guides:
I then walked through the setup outlined in the TDD Kata, as far as the beginning of Test #1. Around this stage, I spent maybe two hours trying to get my classes to implement the interface as described, but getting blocked by the way they all inherited from phone specific classes.. So I moved away from getting 'unit tests' per the usual definition here, and wrote some more general tests - mostly only the simple ones that didn't require me building any fake objects. A few specific points that tripped me up
- A test failure (Assert.Fail or even Assert.Inconclusive) is treated as an exception during debugging, and there appears to be no way to turn this off. If, like me, you just wrote a bunch of tests that fail and you want to debug a specific one, you'll just have to Continue a lot.
- to use the (Tag[""]) functionality, you need "using Microsoft.Silverlight.Testing" and not just "using Microsoft.Silverlight.UnitTesting".

The next week, I realised that I wanted to get my app update published, and I didn't want to publish all the new test code I was writing. To get the update published ASAP, I created a new WindowsPhone Test Project, pulled out all the test code (handily saved into the Test folder for easy extraction) and shipped the existing app with a link to my survey added.

When I launched the new test project, I found that it crashed immediately when it started running the tests - and I couldn't run it in debug mode to figure out why. While looking for tips on how I should have set up this project, I found that the creator of this project, Jake Ginnivan, had done the 'building testable phone objects' work for me in the Windows Phone Essentials toolkit. Eventually I discovered that the problem was the exceptions thrown by failed tests (noted earlier) - so the Test Project was essentially useless to me. It's possible I simply missed the option to run it in debug mode, but my solution was to create a regular Windows Phone App project, and put the tests in there where I could safely run under debug mode. While investigating this I found another tutorial - Catel - Part 8 of n: WP7 Mango and unit testing the camera.

So, the current status of the project is
- need to reimplement my core MVVM framework with testable objects
- need to write actual unit tests around each base class
- I have about half the broader tests passing.Currently I'm working on one that fails because it doesn't wait for the asynchronous object population to complete. I think that's worth a whole new post.

While poking around in all these investigations, I also installed these useful looking dev tools, which I haven't yet explored:

PAX Digital Assistant: up to now

My plan for this blog is to be mostly about my app development work - building, testing, designing, using toolkits and frameworks and so on. I have one app under development and ideas for more. This post gives the background of my current app. 

In the beginning - conception, ambition, scaling back, release
Late 2010, when the SDK for Windows Phone had been released and I was all excited about building an app, I realised that I should build an app for PAX. I began, but didn't get anything done in time for PAX of that year. Then I bought tickets to PAX East 2011, and decided that I would have an app out for that. I looked into MVVM programming, and got pretty much my first taste of actually using an MVC pattern (big props to Laurent Bugnion's toolkit). I was practicing all my (underdeveloped) project management skills, creating user stories, sketching out the interface, etc. Shockingly, I didn't give much thought to testing it (pretty egregious oversight, given that I'm an SDET).



Unsurprisingly, my first ideas were ridiculously ambitious - it should interface with twitter, allowing you to follow all the pax-related accounts, and to tweet, and it would automatically append a #pax tag to any tweets you sent, and you should be able to view the map and zoom in from a suburb level right to a room level, and make notes on the map and share them with your friends in realtime. I handwrote the events into a custom, simple-as-possible xml format, then saved this schedule into the app itself (easy at the time, but meant that a full update was required for any schedule changes). As the dates got closer, I started cutting features. I actually got the app through certification about a week before PAX began, and then had to create an update with the full schedule that made it to the app store the day of PAX East 2011. I was unbelievably proud, and seeing the (mostly positive) reviews and getting a few emails from users was an amazing feeling.

version 2 - poor design bites back
I planned to improve it for PAX Prime, August, but in the end didn't really make any changes - my clunky overall design meant that simply updating all the content to be relevant for Prime was an effort. At PAX Prime I had some new users, but still a few bugs.  In particular, some users complained it was crashing frequently, which I couldn't repro. Eventually one of the users figured out that if he switched his region format from Canada to the USA, it stopped crashing - I thought I'd covered all my bases by randomly testing in region formats like french, two cyrillic languages and an asian language, but no. Immediately after PAX I was still motivated enough to do some work, and I fixed this bug as well as implementing a search feature among all the events.

doing it all right this time, for real
Coming up now we have PAX East 2012. I am in the process of redesigning the app under a test driven framework, so that I can add some major new features like exporting your scheduled events to your calendar, sharing them with friends on an associated website, and updating the event list from a website rather than releasing a new version of the app each time the schedule changes.  I created a Trello board to track what I'm doing - I have mostly been pretty consistent at keeping all my notes and sketches on my ipad (I use NoteTaker HD), but a dedicated task tracker seems like it'll make life easier. I decided that it would be useful to get more feedback from users (related: I'm taking a User Centred Design Certificate) so I wrote a survey, piloted it on three friends who used the app, and then published (well, submitted for certification, so far) an update that adds a link to this survey in the about page and a notice the first time the user opens it asking them to go take the survey. I also have some feedback in email already from users who contacted me through my about page.

Next few posts will probably cover
 - how I'm building the test framework for my app, and problems I've run into where my design isn't test friendly
- installing and beginning to work with the Skydrive API
- setting up the website for the schedule to update from