首页 > 解决方案 > 什么样的单元测试对 python 中的聊天机器人有意义?

问题描述

我现在正在创建一个简单的聊天机器人,现在我想使用 unittests 包对其进行测试。我是编程新手,最近才听说单元测试的存在。我认为对于要测试的聊天机器人,看看它是否为正确的用户输入提供了正确的输出是有意义的。因此,例如,如果用户写“Hi”,它应该输出“Hey what's up?” 如库中指定的(我已经为它编写了一堆库;它不是深度学习机器人)。

这是我的聊天机器人的代码:

# importing regular expression operations, which we need later to access the libraries

import re 
import random # later we want to pick a chatbot answer to a statement by random
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona  # import libraries
# and here we imported all the topic libraries      

class JordanBot:
    """
    A class that represents the abilities of Jordan the chatbot.
    ...

    Attributes
    ----------
    name : str
        user can insert name, which will later be shown in the chat.

    Methods 
    ----------
    name : str
        user can insert name, which will later be shown in the chat.

    """


    def __init__(self, name): # this function is always called when a new object of the class is called
        """
        Constructing topics for Jordan. Takes the user's name as an argument. 

        """        

        self.name = name


    def chat(self): 
        """
        A function that enables chatting with Jordan after picking a topic.
        Take no arguments.

        """       

        topics = [dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona]

        while True:
            print("Welcome. My name is Jordan. You can now choose a topic that we can talk about.")
            print("Press '0' to have some good old-fashioned smalltalk.")
            print("Press '1' to tell me about your deepest sorrows and your destroyed soul.")
            print("Press '2' to curse with me.")
            print("Press '3' to meditate with me.")
            print("Press '4' to talk about Corona.")
            # execute this welcome text and tell user what to press in order to pick a topic.

            choice = input(">>> ")
            # initialize input

            if choice == '0': # determine which key to press to initiate the specific topic
                print("Alrighty, let's do some chitchatting.")# initiate welcome text for specific topic
                print("Don't forget that I am sensitive to punctuation.")
            elif choice == '1':
                print("Please tell me about your deepest sorrows and your destroyed soul.")
                print("Don't forget that I am sensitive to punctuation.")  
            elif choice == '2':
                print("Make yourself ready. let's insult each other!")
                print("Don't forget that I am sensitive to punctuation.")
            elif choice == '3':
                print("Ok then, let's meditate.")
                print("Don't forget that I am sensitive to punctuation..")
            elif choice == '4':
                print("Let's talk about Corona.")
                print("Don't forget that I am sensitive to punctuation..")
            elif choice == 'q': # if user wants to quit
                break
            else: # if user pressed the wrong key.
                print("Try again.")

            edition = topics[int(choice)]
            statement = list(map(lambda x:re.compile(x[0], re.IGNORECASE), edition)) 
            # list(map()) applies a function to all elements of a specified object, in this case the cursing library
            # lambda makes sure that re.compile is applied in a certain way to all elements of the library without being case-sensitive
            # re.compile makes sure that the elemets are turned into objects that can be matched later to another item in the library    
            answer = list(map(lambda x:x[1], edition))
            # same here, but here we pick the second argument in the list x[1], which entails Jordan's answers


            while True:
                userInput = input(' ' + self.name + ' >>> ') # this allows for the user to type in keys
                resp = "I did not understand what you said. Also, I am sensitive to punctuation." # initalize response variable
                counter = 0  # initalize counter
                while resp == "I did not understand what you said. Also, I am sensitive to punctuation." and counter < len(statement): # determine when to start my loop
                    for i in range(0, len(statement)): # loop through the indexed library
                        match = statement[i].match(userInput) # look if input of the user matches with one of the words in the library
                        if match:
                            word = statement[i].split(userInput)[1]  # We have to take the first element of this list
                            resp = random.choice(answer[i]) # if there is a match, pick a random answer from x[1]
                        counter += 1 # make sure that the counter is now + 1 so it does not write the initialized response from the beginning but continues with the loop
                                     # if there is no match though, then it will write the initialized answer
                if userInput == 'q':
                    print(random.choice(answer[i]))
                    print("---------------------------------")
                    print("Do you want to choose another topic? Pick below or press 'q' to quit for realsies.")
                    print("---------------------------------")
                    break
                resp = resp.format(word)
                print('____________')
                print('                                                    ')
                print('Jordan >>> ' + resp) # print Jordan's answer

我正在尝试创建的单元测试类似于:

import unittest
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona # import dictionairies

from Jordan_Class import JordanBot

class testJordan(unittest.TestCase):
    """
    A class to test several units of Jordan to make sure everything is working correctly.
    """

    def test_match(self):

        j = JordanBot('StringName')
        j.chat()
        user_input = "What are you?"
        bot_output = list(map(lambda x:x[1], dict_smalltalk)) # this is how I access the right response in the right library
        matched = bot_output.match(user_input)
        self.assertIn("I am a chatbot, dude. What do you think?", matched)

    def test_regex(self):

        j = JordanBot('StringName')
        j.chat()
        text = 'something'
        regex = {}
        self.assertRegexpMatches(text, regex)

if __name__ == '__main__':
    unittest.main()


主要问题是这些行只运行我的代码,而不是真正的任何单元测试。非常感谢您的建议!

标签: pythonunit-testingchatbot

解决方案


推荐阅读