GET request test, assert error, python

GET request test, assert error, python

Postby MrFRZ » Thu Jun 09, 2016 4:21 pm

Hi, Im trying to write a simple test case for testing a http get request, however Im getting a strange assertion error. Im using urllib & urllib2 in python.
My test function code:
Code: Select all
def test_get(self):
    req = urllib2.Request('http://127.0.0.1:5000/api/assets')
    response = urllib2.urlopen(req)
    print response.read()
    assert response.read() == [{
        "id": 1,
        "ip": "111.111.111.1",
        "password": "Pass1",
        "title": "1st"
    }, {
        "id": 2,
        "ip": "222.222.222.2",
        "password": "Pass2",
        "title": "2nd"
    }]

The above code sends a GET request to a locally hosted server. The route calls another function in a separate file that connects to a database (Im using flask and sqlalchemy to do this if that helps). The function converts the database entries into a dictionary for each row, then returns a jsonified list of the dictionaries.
In this test case I setup the database with dummy data before calling test_get(). I know the data is properly stored in the database and that the function called by the route returns the correct data from the database.
In the terminal I use nosetests to run the file individually and get this in response:
Code: Select all
Traceback (most recent call last):
  File "/some_directory/file.py", line 47, in test_get
    "title": "2nd"
AssertionError:
-------------------- >> begin captured stdout << ---------------------
[{"ip": "111.111.111.1", "password": "Pass1", "id": 1, "title": "1st"}, {"ip": "222.222.222.2", "password": "Pass2", "id": 2, "title": "2nd"}]

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 1 test in 0.705s

FAILED (failures=1)

The captured stdout is from the print statement I threw into my function, and it shows exactly what I'm trying to assert, which is what confuses me.

My question is why is the assert failing? Am I calling the route correctly? If not, what am I doing wrong? I'm fairly new to Python and object oriented languages, sorry if this is something simple that I've just missed. Thanks
Last edited by micseydel on Thu Jun 09, 2016 4:22 pm, edited 1 time in total.
Reason: Initial post lock.
MrFRZ
 
Posts: 4
Joined: Thu Jun 09, 2016 3:58 pm

Re: GET request test, assert error, python

Postby Ofnuts » Thu Jun 09, 2016 7:13 pm

What is the actual type of response.read()? You are comparing it with a list of two dictionaries, but it is likely only a string at this point, and you would have to de-JSON-ize it first...

Btw, the requests module ("HTTP for humans") is a lot easier to use that urllib* and has a json() method on requests results.
This forum has been moved to http://python-forum.io/. See you there.
User avatar
Ofnuts
 
Posts: 2659
Joined: Thu May 14, 2015 9:46 am
Location: Paris, France, EU, Earth, Solar system, Milky Way, Local Cluster, Universe #32987440940987

Re: GET request test, assert error, python

Postby MrFRZ » Thu Jun 09, 2016 8:33 pm

Welp, switching to the request methods makes things a lot easier, the POST, PATCH, and DELETE methods should be pretty straightforward now. Thanks, I don't know how I missed this library
MrFRZ
 
Posts: 4
Joined: Thu Jun 09, 2016 3:58 pm

PATCH test error, No JSON object...

Postby MrFRZ » Fri Jun 10, 2016 7:53 pm

Alright, so writing the rest of my tests was pretty straight forward from the library Ofnuts linked me to, and I have the GET, POST, and DELETE request tests working fine. However in my PATCH test something is going wrong and google hasn't been able to solve my problem.

The Error I recieve:
Code: Select all
Traceback (most recent call last):
  File "/some_user_dir/some_dir/file.py", line 101, in test_patch
    assert gr.json() == {
  File "/some_user_dir/some_dir/local/lib/python2.7/site-packages/requests/models.py", line 812, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
-------------------- >> begin captured logging << --------------------
requests.packages.urllib3.connectionpool: INFO: Starting new HTTP connection (1): 127.0.0.1
requests.packages.urllib3.connectionpool: DEBUG: "PATCH /api/assets/3 HTTP/1.1" 200 12
requests.packages.urllib3.connectionpool: INFO: Starting new HTTP connection (1): 127.0.0.1
requests.packages.urllib3.connectionpool: DEBUG: "GET /api/assets/3 HTTP/1.1" 500 None
--------------------- >> end captured logging << ---------------------

My PATCH test function:
Code: Select all
def test_patch(self):
    payload = {
        "ip": "x.X.x.X",
        "bad": "parameter"
    }
    headers = {'content-type': 'application/json'}

    pr = requests.patch('http://127.0.0.1:5000/api/assets/3',
                        data=json.dumps(payload),
                        headers=headers)
    gr = requests.get('http://127.0.0.1:5000/api/assets/3')

    assert pr.text == 'Data Patched'
    assert gr.json() == {
        "id": 3,
        "ip": "x.X.x.X",
        "password": "Pass3",
        "title": "3rd"
    }

In the above function, I'm sending a payload with a dictionary containing one valid parameter to change, and one bad parameter my function should filter out. I seem to be following the proper footprint as shown in the link Ofnuts referenced me to, here: http://docs.python-requests.org/en/v0.10.6/api/#requests.patch. The PATCH and POST tests seem to be identical functions (other than the request call and the payload being sent) and my POST test runs fine. This leads me to believe the PATCH function itself (the one being tested) is wrong. So I tried running a curl command in the terminal, it worked perfect; however when the test file is run via nosetests, the data sent (ip) isn't altered to x.X.x.X

When the route /api/assets/<int:data_id> is called, this line is executed: patch_data_by_id(data_id, flask.request.get_json())
Which calls the following function:
Code: Select all
def patch_data_by_id(data_id, keyparams):
    obj = Data.query.filter_by(id=data_id).first()

    for key in keyparams:
        if hasattr(obj, key):
            db.session.query(Data).filter_by(id=data_id).\
                update({key: keyparams[key]})
            db.session.commit()
    return 'Data Patched'

I'm assuming the data isn't altered because the test fails?? if the test succeeded would the database change go through?
I also tried temporarily changing the request.get to check for unchanged data at index 3 (the index I'm trying to PATCH), to at least see if the PATCH function wasn't working, however I got an assertion error, the data still didnt match.
In the Traceback I've shown, the captured logging shows a return of 500 and None, Im guessing this means there was an error in my GET function, but this is really odd. All the GET function is doing is returning the data from the index it was sent. The GET function works fine in the previous 2 tests, so why would it error here if its doing the same thing? Going to the /api/assets route in my browser shows the correct data with an index of 3 sitting right there. AND going to the specific route /api/assets/3 shows the correct data as well.
I've checked to make sure I'm sending and receiving JSON, as that was my error last time, and I am, so I'm a pretty lost as to what is causing the value error, to me my logic makes sense, but I have to be doing something wrong... :(
MrFRZ
 
Posts: 4
Joined: Thu Jun 09, 2016 3:58 pm

Re: PATCH test error, No JSON object...

Postby MrFRZ » Fri Jun 10, 2016 8:51 pm

UPDATE: I now suspect PATCH is failing because I've found that nosetests does not run the tests in the order they are defined in the class... This means when I try to patch index 3 before it is created in the POST test, it fails and GET returns None because there is nothing there yet. This is the only logical thing I can think of to explain this, and also would explain why my DELETE test also failed once or twice randomly.

EDIT: I have altered my tests to be totally independent of one another, nosetests now executes without error. This was my issue 8-)
MrFRZ
 
Posts: 4
Joined: Thu Jun 09, 2016 3:58 pm

Re: GET request test, assert error, python

Postby Ofnuts » Fri Jun 10, 2016 10:51 pm

Good :)
This forum has been moved to http://python-forum.io/. See you there.
User avatar
Ofnuts
 
Posts: 2659
Joined: Thu May 14, 2015 9:46 am
Location: Paris, France, EU, Earth, Solar system, Milky Way, Local Cluster, Universe #32987440940987


Return to Web Development

Who is online

Users browsing this forum: No registered users and 3 guests