wfefefwfew wfefefwfew - 7 months ago 24
Python Question

Testing django methods

Developing a simple chat system via Django - I've implemented some methods for sending/receiving messages.

For example ( this isn't my implementation but just an example one from another chat application ) :

def post(request):
time.sleep(2)
if not request.is_ajax():
HttpResponse (" Not an AJAX request ")
if request.method == 'POST':
if request.POST['message']:
message = request.POST['message']
to_user = request.POST['to_user']
ChatMessage.objects.create(sender = request.user, receiver = User.objects.get(username = to_user), message = message, session = Session.objects.get(session_key = request.session.session_key))

return HttpResponse (" Not an POST request ")


Now that I have the method written - I need to test to see if the message is added. At this point I have not written any JavaScript for I.e. intervals to refresh and wait for messages ect. Should I go straight into writing JS or test this method first and see if it works correctly then write the JS for it? sounds like an idiotic question but I'm finding it hard to understand how I'd go about testing the method...

Answer

In my opinion it doesn't matter. You will find many developers who are test-before, and many who are test-after. Implement it in whatever order you prefer. Sometimes when in haste it is easier to write a working prototype without any tests first (especially if the interfaces aren't finalized and still change a lot during development, in this case you don't waste time by adjusting a lot of tests every time you have to change some interfaces.). Just don't be lazy to write the tests at least when you already have the finalized interfaces.

What really matters is to have a well defined interfaces. From a backend perspective you will have an interface implementation (the view in this case) and one or more users for the interface: both the frontend and the client are users of the backend implementation but there could be even more. After having the interface it really doesn't matter which one you implement first. By mocking the interface (faking server responses with pre-baked possibly constant data) you can write only a frontend without any backend code. You can write the server first, or a the tests... You decide.

In teams where you have specialized developers (frontend/backend) you can agree on an interface and then both on the frontend and the backend side you can "mock" (fake) the other side of the interface: The frontend guys write some code that emulates the server responses with some fake data, and the backend guys write some tests that emulate the client with some fake requests. This way the frontend and backend team doesn't have to wait for each other to finish with the code and both the frontend and the backend are testable alone. Of course later it is recommended to add end-to-end (e2e) testing that tests the whole stack connected together.

Again, what really matters most is usually having well defined interfaces and not the code that is written around the interfaces. In crappy systems the problem is usually that you have only code without interfaces... If a system is architecturally well built and the interfaces are well defined then quite a lot of crappy code written around the interfaces can be manageable.

In case of django views that have a well defined interface I usually develop the backend first along with the tests. In your case the django test is super simple: You just create a django test client (https://docs.djangoproject.com/en/1.8/topics/testing/tools/#test-client), post some fake requests with it to simulate the client and then you check whether the db contains the expected objects as a result.

Some additional advices:

  • Decorate your view with @require_POST
  • I think you shouldn't use request.is_ajax() to deny responding to the client. request.is_ajax() is usually used to find out what kind of response is needed by the client. If the POST request was sent by a form of an html page then you want to generate another html page as a response. If the request was sent using ajax then you usually want to respond with processable data (json, xml, etc...) instead of html.
Comments