2016-12-21 8 views
-1

私はPython 2.7で単に「行う」というアプリしか持っていませんでした。これはPythonユニットテストで初めてのことです。単体テストのアイデアを知りたいだけです。Pythonで単体テストを書く良い方法

  1. 私が正しい方向に向かいつつあるかどうかは誰か分かりますか?
  2. このテストを改善するにはどうすればよいですか?
  3. IndexErrorのメッセージをチェックする方法は正しいですか?このため( "はIndexError( '注doesnの\' トンが存在し ')" またははIndexError(' 返さより1つのエントリー ')当時)

アプリケーション:

# 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() 

答えて

-1

ドキュメントを確認しましたか? doctestを参照してください。単体テストをPythonコードに統合する簡単な方法です。もう1つの選択肢はunittestフレームワークです。

+0

私はお金をかけてくれてありがとうございました。 –

関連する問題