我收到这个奇怪的错误,我无法理解原因。我之前的项目中已经尝试过这种方法,但是使用Selenium比使用纯API测试用例更多的是在前端。
以下是代码:
from django.test import TestCase
from django.core.urlresolvers import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from unittest import skip # This library is used to skip some class TestCase
from . models import *
import time # This library is used in case you want to put a sleep before proceeding to the next line of scripts
import inspect # This library is used to print the method of that certain class.. inspect.stack()[0][3]
import json # This library is for parsing the response.content
# Create your tests here.
url_1 = reverse('artists-list') # The URL endpoint for the artists which is /artists/ having POST and GET methods
url_2 = reverse('artists-detail', kwargs={'artist_id':1}) # The URL endpoint for the artists which is /artists/:d having GET, PUT and DELETE methods
url_3 = reverse('artists-detail', kwargs={'artist_id':3}) # Wrong id endpoint on purpose to check error response
# Check the response if there is no given data
class ArtistTestWithData(APITestCase):
# indent is just used to specify the tab size
# follow the json naming format
# Command: python manage.py dumpdata store.artist --indent=2 > store/fixtures/artists_2016_07_23.json
fixtures = ['artists_2016_07_23.json']
# Check the response if there is a data within
def test_get(self):
# self.client attribute will be an APIClient instance
# Basically it will act as a client
response = self.client.get(url_1)
data = json.loads(response.content)["data"]
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNotEqual(len(data), 0) # There should be a data
# print ("%s.%s DONE - 1" % (self.__class__.__name__, inspect.stack()[0][3]))
# Check the response if there is no given data
class ArtistTest(APITestCase):
# For reusable of adding a single record
# To be used for POST, GET(detailed), PUT and DELETE
def _setup_add_record(self):
_data = {"name": "50 Cent", "birth_date":"2005-02-13"}
response = self.client.post(url_1, _data)
data = json.loads(response.content)["data"]
return ( response, _data, data )
# Checks the records
def test_get(self):
# self.client attribute will be an APIClient instance
# Basically it will act as a client
response = self.client.get(url_1)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(response.content, '') # There should be no data
# self.assertEqual(len(data), 0)
# print ("%s.%s DONE - 1" % (self.__class__.__name__, inspect.stack()[0][3]))
# Creates the record
def test_post(self):
x = self._setup_add_record()
self.assertEqual(x[0].status_code, status.HTTP_201_CREATED) # Status 201 is the default when a new object is created
self.assertEqual(x[2], x[1]) # have the API return the updated (or created) representation as part of the response
self.assertEqual(Artist.objects.count(), 1) # Make sure that there is a craeted instance
self.assertEqual(Artist.objects.get().name, '50 Cent') # Double checking if the last post is the created instance
# Get a specific record
def test_get_detail(self):
x = self._setup_add_record()
response = self.client.get(url_2)
data = json.loads(response.content)["data"]
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(data, x[1])
self.assertNotEqual(len(data), 0)
# Update a specific record
def test_put(self):
x = self._setup_add_record()
update = {"name": "60 Cents", "birth_date":"2005-02-13"}
response = self.client.put(url_2, update)
data = json.loads(response.content)["data"]
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNotEqual(data, x[1])
self.assertNotEqual(Artist.objects.get().name, '50 Cent') # Check if it is still the old name
self.assertEqual(Artist.objects.get().name, '60 Cents') # Check the new name
def test_delete(self):
x = self._setup_add_record()
response = self.client.delete(url_2)
self.assertEqual(response.status_code, status.HTTP_200_OK)
response = self.client.get(url_2)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
# Check the response if there is error on requests
class ArtistTestErrors(APITestCase):
def test_post(self):
_data = {"birth_date":"2005-02-13"}
response = self.client.post(url_1, _data)
data = json.loads(response.content)["errors"] # checks the errors
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertNotEqual(len(data), 0)
def test_get_detail(self):
ArtistTest._setup_add_record(self)
response = self.client.get(url_3)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
这是错误:
line 103, in test_get_detail
ArtistTest._setup_add_record(self)
TypeError: unbound method _setup_add_record() must be called with ArtistTest instance as first argument (got ArtistTestErrors instance instead)
答案 0 :(得分:1)
问题出在以下代码中:
def test_get_detail(self):
ArtistTest._setup_add_record(self)
response = self.client.get(url_3)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
您无法调用ArtistTest._setup_add_record
之类的实例方法。您需要创建一个所有调用ArtistTest()._setup_add_record
如果你想使用该方法是不同的类,那么去继承/混合:
class ArtistRecordSetupMixing():
# For reusable of adding a single record
# To be used for POST, GET(detailed), PUT and DELETE
def _setup_add_record(self):
_data = {"name": "50 Cent", "birth_date":"2005-02-13"}
response = self.client.post(url_1, _data)
data = json.loads(response.content)["data"]
return ( response, _data, data )
在需要功能的测试用例中:
# Check the response if there is no given data
class ArtistTest(ArtistRecordSetupMixing, APITestCase):
pass