我只是“做”'应用程序在python 2.7中,我为此编写了一些单元测试。这是我第一次使用python单元测试,我只是想知道单元测试的想法。
App:
# coding: utf-8
from __future__ import unicode_literals
from shutil import copyfile
import json
import os
DATABASE = 'notes_data/notes.json'
BOARDS = ['to do', 'in progress', 'done']
class NotesManagerMixin(object):
def count(self):
return len(self.notes)
def filter(self, *args, **kwargs):
result = self.notes
for key, value in kwargs.iteritems():
result = [
note for note in result
if getattr(note, key, None) == value or
note.message.startswith(str(value)) or
note.message.endswith(str(value))
]
return NotesQueryset(result)
def get(self, *args, **kwargs):
notes = self.filter(*args,**kwargs)
if notes.count() == 0:
raise IndexError('Note doesn\'t exist')
elif notes.count() == 1:
return notes[0]
else:
raise IndexError('Returned more then one entry')
def first(self):
return self.notes[0]
def last(self):
return self.notes[-1]
class NotesQueryset(NotesManagerMixin):
def __init__(self, notes):
self.notes = [note for note in notes]
def update(self, *args, **kwargs):
for note in self.notes:
for key, value in kwargs.items():
setattr(note, key, value)
note.save()
return self
def delete(self):
for note in self.notes:
note.delete()
return self
def __getitem__(self, idx):
return self.notes[idx]
def __str__(self):
return str(self.notes)
def __repr__(self):
return self.__str__()
class NotesManager(NotesManagerMixin):
def __init__(self):
self.notes = []
def __iter__(self):
return self.next()
def __generate_id(self):
"""
Funkcja pomocnicza do pobrania pewnej wolnej wartości indexu.
"""
try:
return max(note.id for note in self.notes) + 1
except ValueError:
return 1
def all(self):
return NotesQueryset(self.notes)
def add(self, idx, board, message):
self.notes.append(Note(idx=idx, board=board, message=message))
def create(self, board, message):
note = Note(
idx=self.__generate_id(),
board=board,
message=message
)
note.clean()
self.notes.append(note)
note.save()
return note
def next(self):
for note in self.notes:
yield note
def to_dict(self):
return [note.to_dict() for note in self.notes]
class Note(object):
objects = NotesManager()
def __init__(self, idx, board, message):
self.id = idx
self.board = board
self.message = message
def __str__(self):
return 'ID: {}, Board: {}, Message: {}'.format(
self.id,
self.board,
self.message
)
def __repr__(self):
return self.__str__()
def clean(self):
if not self.message:
raise ValueError('Message is required')
if self.board not in BOARDS:
raise ValueError('Board "{}" doesn\'t exists'.format(self.board))
if type(self.id) != int:
raise ValueError('Note id "{}" is invalid'.format(self.id))
def save(self):
for key, note in enumerate(self.objects):
if note.id == self.id:
self.objects.notes[key] = self
break
with open(DATABASE, 'w') as database_file:
json.dump(self.objects.to_dict(), database_file, indent=4)
return True
def delete(self):
for key, note in enumerate(self.objects.notes):
if note.id == self.id:
self.objects.notes.pop(key)
with open(DATABASE, 'w') as database_file:
json.dump(self.objects.to_dict(), database_file, indent=4)
def to_dict(self):
return {
'id': self.id,
'message': self.message,
'board': self.board
}
def load_initial_data():
with open(DATABASE, 'r') as database_file:
json_data = json.load(database_file, encoding='utf-8')
for item in json_data:
Note.objects.add(
idx=item['id'],
board=item['board'],
message=item['message'],
)
load_initial_data()
单元测试:
import unittest
from notes_manager_v2 import NotesQueryset, Note, load_initial_data, NotesManagerMixin
class TestNotesQueryset(unittest.TestCase):
def test_filter(self):
actual = Note.objects.all().filter(board='in progress') # get all notes with board 'in progress'
expected = []
for note in Note.objects.all():
if note.board == 'in progress':
expected.append(note)
self.assertItemsEqual(actual, expected)
def test_get(self):
actual = [Note.objects.all().get(id=1)] # get note with method get
expected = []
for note in Note.objects.all(): # search note with index 1
if note.id == 1:
expected.append(note)
self.assertEqual(actual, expected)
def test_get_fail_1(self):
self.assertRaises(IndexError, lambda:Note.objects.all().get(id=9868976)) # thos note dont exist should raise IndexError
def test_update(self):
from_board = 'to do'
to_board = 'done'
before_change = Note.objects.filter(board=from_board) # use filter method to get all notes with board 'to do'
actual = Note.objects.filter(board=from_board).update(board=to_board) # update all board
self.assertNotEqual(before_change, actual) # check for difference
notes = Note.objects.all()
for note in actual:
self.assertIn(note, notes) # check notes are updated
def test_delete(self):
to_delete = Note.objects.filter(id=2).delete() # find note with filter method and delete it
notes = Note.objects.all()
self.assertNotIn(to_delete, notes)
def test_create(self):
new_note = Note.objects.create(message='lorem ipsum', board='in progress') # create new note
notes = Note.objects.all()
self.assertIn(new_note, notes) #
if __name__ == '__main__':
unittest.main()