Commit 9b1c33f0 by Filippo Valsorda

Add a Python test suite running in the workbench

parent a7958491
...@@ -51,3 +51,5 @@ docs/_build/ ...@@ -51,3 +51,5 @@ docs/_build/
# PyBuilder # PyBuilder
target/ target/
workbench.db
...@@ -25,3 +25,33 @@ $ pip install -e . ...@@ -25,3 +25,33 @@ $ pip install -e .
``` ```
from the XBlock folder and add `drag-and-drop-v2` to your Advanced Module List. from the XBlock folder and add `drag-and-drop-v2` to your Advanced Module List.
## Testing
1. In a virtualenv, run
```bash
$ (cd .../xblock-sdk/; pip install -r requirements.txt)
$ (cd .../xblock-drag-and-drop-v2/; pip install -r tests/requirements.txt)
```
2. In the xblock-sdk repository, create the following configuration file in `workbench/settings_drag_and_drop_v2.py`
```python
from settings import *
INSTALLED_APPS += ('drag_and_drop_v2',)
DATABASES['default']['NAME'] = 'workbench.db'
```
3. Run this to sync the database before starting the workbench (answering no to the superuser question is ok):
```bash
$ .../xblock-sdk/manage.py syncdb --settings=workbench.settings_drag_and_drop_v2
```
4. To run the tests, from the xblock-drag-and-drop-v2 repository root:
```bash
$ DJANGO_SETTINGS_MODULE="workbench.settings_drag_and_drop_v2" nosetests --rednose --verbose --with-cover --cover-package=drag_and_drop_v2
```
mock
nose
coverage
rednose
-e .
{
"zones": [
{
"index": 1,
"width": 200,
"title": "Zone A",
"height": 100,
"active": true,
"y": "200",
"x": "100",
"id": "zone-1"
},
{
"index": 2,
"width": 200,
"title": "Zone B",
"height": 100,
"active": true,
"y": 0,
"x": 0,
"id": "zone-2"
}
],
"items": [
{
"displayName": "A",
"feedback": {
"incorrect": "No A",
"correct": "Yes A"
},
"zone": "Zone A",
"backgroundImage": "",
"id": 0,
"size": {
"width": "190px",
"height": "auto"
}
},
{
"displayName": "B",
"feedback": {
"incorrect": "No B",
"correct": "Yes B"
},
"zone": "Zone B",
"backgroundImage": "",
"id": 1,
"size": {
"width": "190px",
"height": "auto"
}
},
{
"displayName": "X",
"feedback": {
"incorrect": "",
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"id": 2,
"size": {
"width": "100px",
"height": "100px"
}
},
{
"displayName": "",
"feedback": {
"incorrect": "",
"correct": ""
},
"zone": "none",
"backgroundImage": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"id": 3,
"size": {
"width": "190px",
"height": "auto"
}
}
],
"state": {
"items": {},
"finished": true
},
"feedback": {
"start": "Intro Feed",
"finish": "Final Feed"
},
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png"
}
import logging
import json
import re
import datetime
import time
import json
from webob import Request
from mock import Mock, patch
from workbench.runtime import WorkbenchRuntime
from xblock.runtime import KvsFieldData, DictKeyValueStore
from nose.tools import (
assert_equals, assert_true, assert_in,
assert_regexp_matches
)
import drag_and_drop_v2
# Silence too verbose Django logging
logging.disable(logging.DEBUG)
def make_request(body):
request = Request.blank('/')
request.body = body.encode('utf-8')
return request
def make_block():
runtime = WorkbenchRuntime()
key_store = DictKeyValueStore()
db_model = KvsFieldData(key_store)
return drag_and_drop_v2.DragAndDropBlock(runtime, db_model, Mock())
def test_templates_contents():
block = make_block()
block.display_name = "Test Drag & Drop"
block.question_text = "Question Drag & Drop"
block.weight = 5
student_fragment = block.render('student_view', Mock())
assert_in('<section class="xblock--drag-and-drop">',
student_fragment.content)
assert_in('<option value="{{ value }}">{{ value }}</option>',
student_fragment.content)
assert_in("Test Drag &amp; Drop", student_fragment.content)
assert_in("Question Drag &amp; Drop", student_fragment.content)
assert_in("(5 Points Possible)", student_fragment.content)
studio_fragment = block.render('studio_view', Mock())
assert_in('<div class="xblock--drag-and-drop editor-with-buttons">',
studio_fragment.content)
assert_in('<option value="{{ value }}">{{ value }}</option>',
studio_fragment.content)
def test_studio_submit():
block = make_block()
body = json.dumps({
'display_name': "Test Drag & Drop",
'question_text': "Question Drag & Drop",
'weight': '5',
'data': {
'foo': 1
}
})
res = block.handle('studio_submit', make_request(body))
assert_equals(json.loads(res.body), {'result': 'success'})
assert_equals(block.display_name, "Test Drag & Drop")
assert_equals(block.question_text, "Question Drag & Drop")
assert_equals(block.weight, 5)
assert_equals(block.data, {'foo': 1})
def test_ajax():
assert_equals.__self__.maxDiff = None
block = make_block()
with open('tests/test_data.json') as f:
block.data = json.load(f)
with open('tests/test_get_data.json') as f:
get_data = json.loads(block.handle('get_data', Mock()).body)
assert_equals(json.load(f), get_data)
# Wrong with feedback
data = json.dumps({"val":0,"zone":"Zone B","top":"31px","left":"216px"})
res = json.loads(block.handle('do_attempt', make_request(data)).body)
assert_equals(res, {
"final_feedback": None,
"finished": False,
"correct": False,
"feedback": "No A"
})
with open('tests/test_get_data.json') as f:
get_data = json.loads(block.handle('get_data', Mock()).body)
assert_equals(json.load(f), get_data)
# Wrong without feedback
data = json.dumps({"val":2,"zone":"Zone B","top":"42px","left":"100px"})
res = json.loads(block.handle('do_attempt', make_request(data)).body)
assert_equals(res, {
"final_feedback": None,
"finished": False,
"correct": False,
"feedback": ""
})
with open('tests/test_get_data.json') as f:
get_data = json.loads(block.handle('get_data', Mock()).body)
assert_equals(json.load(f), get_data)
# Correct
data = json.dumps({"val":0,"zone":"Zone A","top":"11px","left":"111px"})
res = json.loads(block.handle('do_attempt', make_request(data)).body)
assert_equals(res, {
"final_feedback": None,
"finished": False,
"correct": True,
"feedback": "Yes A"
})
with open('tests/test_get_data.json') as f:
expected = json.load(f)
expected["state"] = {
"items": {
"0": ["11px", "111px"]
},
"finished": False
}
get_data = json.loads(block.handle('get_data', Mock()).body)
assert_equals(expected, get_data)
# Final
data = json.dumps({"val":1,"zone":"Zone B","top":"22px","left":"222px"})
res = json.loads(block.handle('do_attempt', make_request(data)).body)
assert_equals(res, {
"final_feedback": "Final Feed",
"finished": True,
"correct": True,
"feedback": "Yes B"
})
with open('tests/test_get_data.json') as f:
expected = json.load(f)
expected["state"] = {
"items": {
"0": ["11px", "111px"],
"1": ["22px", "222px"]
},
"finished": True
}
expected["feedback"]["finish"] = "Final Feed"
get_data = json.loads(block.handle('get_data', Mock()).body)
assert_equals(expected, get_data)
{
"zones": [
{
"index": 1,
"title": "Zone A",
"id": "zone-1",
"height": 100,
"y": "200",
"active": true,
"x": "100",
"width": 200
},
{
"index": 2,
"title": "Zone B",
"id": "zone-2",
"height": 100,
"y": 0,
"active": true,
"x": 0,
"width": 200
}
],
"items": [
{
"displayName": "A",
"backgroundImage": "",
"id": 0,
"size": {
"width": "190px",
"height": "auto"
}
},
{
"displayName": "B",
"backgroundImage": "",
"id": 1,
"size": {
"width": "190px",
"height": "auto"
}
},
{
"displayName": "X",
"backgroundImage": "",
"id": 2,
"size": {
"width": "100px",
"height": "100px"
}
},
{
"displayName": "",
"backgroundImage": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"id": 3,
"size": {
"width": "190px",
"height": "auto"
}
}
],
"state": {
"items": {},
"finished": false
},
"feedback": {
"start": "Intro Feed"
},
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png"
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment