2
\$\begingroup\$

It is my second day into software testing and I am currently testing my database, handlers, and functions. I am wondering if I am taking the right approach as this is the first time testing my web app. I'd love to get some advice or feedback to improve my tests!

Below is the code for data model.

class Post(ndb.Model):
    content = ndb.StringProperty(required = True)
    user_key = ndb.KeyProperty(User)
    created = ndb.DateTimeProperty(auto_now_add = True)
    last_modified = ndb.DateTimeProperty(auto_now = True)
    user = ndb.StringProperty(required = True)
    city = ndb.StringProperty()
    coords = ndb.GeoPtProperty()

    def render(self):
        self._render_text = self.content.replace('\n', '<br>')
        params = dict(p = self)

        return render_str("post.html", **params)

    def as_dict(self):
        time_fmt = '%c'
        if self.coords is None:
            coords = "None"
        else:
            coords = self.coords.lat, self.coords.lon
            lat, lon = coords[0], coords[1]
            coords = {'latitude': lat, 'longitude': lon}

        d = {'user': self.user,
             'content': self.content,
             'city': self.city,
             'coords': coords,
             'created': self.created.strftime(time_fmt),
             'last_modified': self.last_modified.strftime(time_fmt)}
        return d

Here's the function.

def make_secure_val(val):
    return '%s|%s' % (val, hmac.new(secret, val).hexdigest())

Here's my tests

def test__PostModel(self):
    post_content = "test content"
    user = "testUser"
    city = "test city"
    u_key = ndb.Key('User', int("123"), parent=users_key())  

    test_model = Post
    p = test_model(parent=post_key(), content=post_content, user=user, user_key=u_key, city=city)
    key = p.put()

    p2 = key.get()

    self.assertEqual('test content', p2.content)
    self.assertEqual(u_key, p2.user_key)
    self.assertEqual('testUser', p2.user)
    self.assertEqual('test city', p2.city)

    try:
        p = test_model()
        key = p.put()
        result = True
    except:
        result = False

    self.assertFalse(result)

def test__get_coords(self):
    coords = "43.653226,-79.383184"
    lat, lon = coords.split(",")
    coords = {"latitude": lat, "longitude": lon}
    coords = json.dumps(coords)
    return coords

    assertIs({"latitude": "43.653226", "longitude": "-79.383184"}, coords)

def test__make_secure_val(self):
    val = "test"
    secret ="testsecret"
    test_result = '%s|%s' % (val, hmac.new(secret, val).hexdigest())

    self.assertEqual("test|e91f3aaeb48b71fc68bddc8ea34dda24", test_result)
\$\endgroup\$
  • 1
    \$\begingroup\$ It is hard to review your unit tests without seeing either the code or the specifications for the code being tested. It's basically a generic hypothetical question at this point. \$\endgroup\$ – 200_success Nov 5 '16 at 5:37
  • \$\begingroup\$ @200_success just added the code. Thanks for your advice! \$\endgroup\$ – Young Nov 5 '16 at 15:24
  • \$\begingroup\$ What is Post? Is it for a blog? \$\endgroup\$ – 200_success Nov 5 '16 at 15:28
  • \$\begingroup\$ @200_success yes. Users' posts are stored into the Post model \$\endgroup\$ – Young Nov 5 '16 at 15:37
3
\$\begingroup\$
try:
    p = test_model()
    key = p.put()
    result = True
except:
    result = False

self.assertFalse(result)

This except clause catches any exception. What you probably intend to test was whether a specific exception occured, so catch that exception and none else.

If you want to make full use of the unittest library (which is what I assume you're using), you can rewrite this block with assertRaises as follows:

with self.assertRaises(YourExpectedException):
    p = test_model()
    key = p.put()

Now, the test__get_coords method doesn't make any sense to me. It unconditionally returns some JSON before it has any chance to assert anything at all. And even after removing the return statement, the code still asserts that some JSON is a dict object. Something is really finshy here!

test__make_secure_val is along the same lines. You're not actually testing the function but implementing it again, which is then what you test. You should probably change it to something like this:

def test__make_secure_val(self):
    test_result = make_secure_val(val)

    self.assertEqual("test|e91f3aaeb48b71fc68bddc8ea34dda24", test_result)

If you want to pass the secret to make_secure_val, add it to the parameter list:

def make_secure_val(val, secret):
    return '%s|%s' % (val, hmac.new(secret, val).hexdigest())
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.