Debugging NoReverseMatch failures in Django

If you get an error like this:

NoReverseMatch at /account/my_webpage

And it points to and error like:

Reverse for 'password_reset_confirm' with arguments '()' and keyword arguments '{u'uidb64': '7ae9a6e950c08946', u'token': u'4g4-2cbcc2bd7311dc9de06520399f4adbe8'}'

And links to some code like:

{% url 'password_reset_confirm' uidb64=uid token=token %}

This message from Django is really not descriptive. What Django is trying to say is:

I cannot find a matching expression in your urls.py file. You will need to add a matching expression like the below to your urls.py file.

url(r'^account/password_confirm', views.password_confirm, name="password_reset_confirm"),

However there still an error:

NoReverseMatch at /account/password_reset
...
1 pattern(s) tried: ['account/password_reset_confirm']

So Django is saying that we have tried a pattern but it does not match. It looks like our pattern does not accept keyword arguments.

Per the Django notes:

https://docs.djangoproject.com/en/1.9/ref/templates/builtins/

Do not mix both positional and keyword syntax in a single call. All arguments required by the URLconf should be present.

We should be good, we do not have mixed arguments and we have just a keyword argument. Let’s set it to handle keyword arguments:

url(r'^account/password_confirm/(?P<uidb64>\w+)/(?P<token>\w+)/', views.password_confirm, name="password_reset_confirm"),

However it still throws error:

NoReverseMatch: Reverse for 'password_reset_confirm' with arguments '()' and keyword arguments '{u'uidb64': '7ae9a6e950c08946', u'token': u'4g4-2cbcc2bd7311dc9de06520399f4adbe8'}' not found. 1 pattern(s) tried: ['account/password_confirm/(?P\\w+)/(?P\\w+)/']

That doesn’t work either, I wonder what is wrong?

Look at the token. Does “\w+” match a dash? NOPE! Let’s match the dash.

url(r'^account/password_confirm/(?P<uidb64>\w+)/(?P<token>[^/]+)/', views.password_confirm, name="password_reset_confirm"),

Now everything works!

Whenever you have a NoReverseMatch error check the following:

  1. Have existing matching url
  2. Match the keyword or positional arguments with that url
  3. Make sure that the argument regular expressions match what you are trying to pass

Ordering Tests in Android UIAutomator Testing

UIAutomator does not normally tests in a specific sequence. This is actually good behavior because your tests in your testing code SHOULD be sequence invariant.

It should not matter what order your tests should run in. If all of your tests are sequence specific, it makes it very difficult to parallelize test in the future and speaks of brittle code.

However in the real world there are often business or code dependencies which force us to order tests. To order tests add the @FixMethodOrder and specify the sorting order. We usually just use name ascending and then name or tests in alphabetical order.

  • t01_checkPreconditions
  • t02_emailNotUpdated

Code Example
The following example will then run in alphabetical sort order:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SmokeTest extends AutomationBaseTest {
    @Test
    public void t01_checkPreconditions() {
        # ...
    }

    @Test
    public void t02_emailNotUpdated() throws InterruptedException {
        # ...
    }
# ...
}

Getting Resource Id’s for Android UIAutomator Testing

When you are testing Android applications you can lookup the object to receive user input either via text or via the resource id.

The resource id is more stable since the text may change dramatically between versions and upon the user interface language.

The best tool is the uiautomatorviewer viewer. It is included in the android sdk tools directory. Launch it via:

cd /path_to_your_android_sdk/android-sdk/tools/
uiautomatorviewer

Then click the second icon from the left which will dump the screen. You can then lookup the resource-id from lower right:

uiautomatorviewer-screenshot

Mutable Deep Copy By Using Categories

Ever run into this error:

mutating method sent to immutable object

The above error means that the program has tried to modify an immutable object. No problem you think. I’ll just make the object mutable. Now the normal way to deal with this is to do:

[obj mutableCopy];

Depending on the calling object, this call returns a mutable copy of the primitive or the objects of an array or hash.

deep-mutable-copy-successful

Great, solution solved! Press the easy button and go to the next problem.

Still reading… No worky?

If you are still reading this then I guess the easy solution did not work for you. If the data structure in question is comprised of deep objects such as trees, JSON objects or other recursive structures you need something more.

Mutable Deep Copy will clone the data structure recursively and allow updating of contained objects no matter how deep the structure.

deep-mutable-copy-fail

In Objective-C, we can attach methods to existing classes via Categories. For deep mutable copy, We attach categories upon the following classes:

  • NSObject
  • NSArray
  • NSDictionary
  • NSSet

This should handle arrays, dictionaries, sets and most primitive objects but one will still need to implement the mutableDeepCopy method on your own custom classes if they are used in the data structure.

Add the following two files into your Xcode project and include them when you need to clone deep recursive structures.

DeepMutableCopy.h

#import <Foundation/Foundation.h>
@interface NSObject (MutableDeepCopy)
- mutableDeepCopy;
@end

DeepMutableCopy.m

#import "DeepMutableCopy.h"
@implementation NSObject (MutableDeepCopy)
- mutableDeepCopy
{
    if([self respondsToSelector:@selector(mutableCopyWithZone:)])
        return [self mutableCopy];
    else if([self respondsToSelector:@selector(copyWithZone:)])
        return [self copy];
    else
        return self;
}
@end

@implementation NSDictionary (MutableDeepCopy)
- mutableDeepCopy
{
    NSMutableDictionary *newDictionary = [[NSMutableDictionary alloc] init];
    NSEnumerator *enumerator = [self keyEnumerator];
    id key;
    while((key = [enumerator nextObject]))
    {
        id obj = [[self objectForKey:key] mutableDeepCopy];
        [newDictionary setObject:obj forKey:key];
    }
    return newDictionary;
}
@end

@implementation NSArray (MutableDeepCopy)
- mutableDeepCopy
{
    NSMutableArray *newArray = [[NSMutableArray alloc] init];
    NSEnumerator *enumerator = [self objectEnumerator];
    id obj;
    while((obj = [enumerator nextObject]))
    {
        obj = [obj mutableDeepCopy];
        [newArray addObject:obj];
    }
    return newArray;
}
@end

@implementation NSSet (MutableDeepCopy)
- mutableDeepCopy
{
    NSMutableSet *newSet = [[NSMutableSet alloc] init];
    NSEnumerator *enumerator = [self objectEnumerator];
    id obj;
    while((obj = [enumerator nextObject]))
    {
        obj = [obj mutableDeepCopy];
        [newSet addObject:obj];
    }
    return newSet;
}
@end

Updating the MySQL ENUM Data Type

Now I am not a big fan of the ENUM data type, it I usually like VARCHAR’s or INT’s better but they do possess a certain value in constraining data to legal values.

However modifying ENUM’s are problematic. Because of several restrictions:

  • You can only append to the end of the enums.
  • You cannot delete a enum.
  • You may not reorder enums.

To modify an enum of ('WHEEL','LEG') try the following:

-- VALID CHANGE - appends to end
ALTER TABLE `ROBOT`
CHANGE COLUMN `ROBOT_LOCOMOTION` `ROBOT_LOCOMOTION`
enum('WHEEL','LEG', 'PROPELLER') DEFAULT 'WHEEL';

However these are not valid changes:

-- INVALID CHANGE - Cannot change ordering
ALTER TABLE `ROBOT`
CHANGE COLUMN `ROBOT_LOCOMOTION` `ROBOT_LOCOMOTION` 
enum('LEG', 'WHEEL', 'PROPELLER') DEFAULT 'WHEEL';

-- INVALID CHANGE - Cannot delete elements
ALTER TABLE `ROBOT`
CHANGE COLUMN `ROBOT_LOCOMOTION` `ROBOT_LOCOMOTION` 
enum('LEG') DEFAULT 'WHEEL';