Automatically test LeetCode use case method

Automatic Merge Test LeetCode Problem Solving Method

When answering questions on leetcode.com, Run Code or Sumbmit usually takes a while to spend. It’s okay if you submit it once and it’s accepted. If you repeat Wrong Answer, it’s a waste of time. In order to increase efficiency and reduce frustration (submitting back and forth, Wrong Answer has been hit), I adopt the method of coding on the local Jupyter notebook, and then submit after passing the test. This article mainly introduces the method of automatic testing.

1. LeetCode mode

After opening a leetcode question, there is a Description tab on the left side. In this tab panel, there are titles, proposition descriptions, and multiple Examples are listed. Each Example has an Input and an Output, and some have an Explanation ; The right side is the coding area, and the coding area automatically generates a class Solution template.

class Solution: def method(self,**kwargs):

For example, the content of Example in the Decription area of ​​question No. 1071 is as follows

The initialization template for the coding area of ​​question 1071 is as follows

2. Jupyter notebook to write code

Copy the content of the coding template in LeetCode to the jupyter notebook, and write the problem-solving code. Suppose the code for Question 1071 is as follows.

class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        if len(str1) < len(str2):
            tmp, str2, str1 = str2, str1, tmp
        len_str2, len_str1 = len(str2), len(str1)
        
        for i in range(1,len_str2+1):
            d2,m2 = divmod(len(str2),i)
            if m2==0 and str2==str2[:d2]*i:
                d1, m1 = divmod(len(str1),d2)
                if m1==0 and str1==str2[:d2]*d1:
                    return str2[:d2]
        return ""

3. Manually test one by one

Manually test one by one, that is, after writing the method content, instantiate the Solution, then copy the Input in each Example in the Decription, pass in the method of the instance, and observe whether the result is consistent with the Output in the Example after execution.

# 实列化类
s = Solution()
# 测试Example中的用例1
# Input: str1 = "ABCABC", str2 = "ABC"
# Output: "ABC"

str1 = "ABCABC"
str2 = "ABC"
s.gcdOfStrings(str1,str2)

'ABC'
# 测试Example中的用例2
# Input: str1 = "ABABAB", str2 = "ABAB"
# Output: "AB"

str1 = "ABABAB"
str2 = "ABAB"
s.gcdOfStrings(str1,str2)
'AB'
# 测试Example中的用例3
# Input: str1 = "LEET", str2 = "CODE"
# Output: ""

str1 = "LEET"
str2 = "CODE"
s.gcdOfStrings(str1,str2)
''
# 测试Example中的用例4
# Input: str1 = "ABCDEF", str2 = "ABC"
# Output: ""

str1 = "ABCDEF"
str2 = "ABC"
s.gcdOfStrings(str1,str2)

''

4. Automatic merge testing

4.1 Copy test case

Copy all the Example content from the LeetCode problem page and assign it to str_Examples. 3 pairs of double quotation marks are used here, and the content can be left intact. The Example description is regular, and the Example description of each question is in the same pattern, so we can define a general method to obtain test cases.

str_Examples ="""Example 1:

Input: str1 = "ABCABC", str2 = "ABC"
Output: "ABC"
Example 2:

Input: str1 = "ABABAB", str2 = "ABAB"
Output: "AB"
Example 3:

Input: str1 = "LEET", str2 = "CODE"
Output: ""
Example 4:

Input: str1 = "ABCDEF", str2 = "ABC"
Output: ""
"""

4.2 Define the method of obtaining use cases

  • The goal is to extract the Input and Output and organize them in pairs.
  • Through observation, regularization split, string split, replace, strip and other methods can be used to extract Input and Output content
  • The input parameters and output are stored in the list, and each use case may have multiple parameters, so the use case parameters are loaded with dict, which is convenient for passing in **kwargs when calling the test method.

Note: Because the """"" used in the input use case document contains double quotation marks ", the quotation marks inside will be regarded as character content after split, resulting in unexpected results.

def get_test_cases(str_examples):
    import re
    params =re.split('Example.+?:',str_examples.replace('\n','').replace(' ',''))[1:]
    cases_arg, cases_ans = [], []
    for param in params:
        kawargs = {}
        args_,ans = param.split('Output:')
        args_ = args_.replace('Input:','').strip().split(',')
        cases_ans.append(ans)
        for arg in args_:
            key,val = arg.split("=")
            kawargs[key] = val
        cases_arg.append(kawargs)
    return zip(cases_arg, cases_ans)

4.3 Defining automated testing methods

  • The default code class name generated by leetcode for each question is Solution, but the function name is selected according to the question and varies from question to question. dir(Solution()) can get the list of method names of Solution, the first part is the built-in method name, and the last part is a custom problem-solving method (only one self-built function is considered here). Use dir(Solution())[-1] to get the function name, and then use getattr to get the instance method f.
  • The input parameter is the result returned by get_usecases - the input and output of the zip-packaged test case, for iteration or taking the input parameter kwargs (Input in Example) and input answer (Output in Example) of each test case.
  • Iterate over the test cases, asserting that f(**kwargs) == answer. If each assertion is successful, return 'Accepted', otherwise try...except catch assertion failure, return 'Wrong Answer'.
def auto_test(test_cases):
    f = getattr(Solution(), dir(Solution())[-1])
    try:
        for kwargs, answer in test_cases:
            print(kawargs,answer)
            assert f(**kwargs) == answer        
        return 'Accepted'
    except Exception as e:  
        print(e)
        return 'Wrong Answer'

4.4 what?! Mysterious problem bug?

  • First call get_test_cases to get the test case, and then pass the result into auto_test for testing, the result is 'Wrong Answer';
  • Directly calling auto_test(get_test_cases()), the result is also 'Wrong Answer'.
  • However, after calling get_test_cases to obtain the test case test_cases, first iterate test_cases, and then pass test_cases into auto_test, and the result is 'Accepted'.
test_cases = get_test_cases(str_Examples)
auto_test(test_cases)
name 'kawargs' is not defined

'Wrong Answer'
auto_test(get_test_cases(str_Examples))
name 'kawargs' is not defined

'Wrong Answer'
for input_args,out in test_cases:
    print(input_args, out)
auto_test(test_cases)    

{'str1': '"ABABAB"', 'str2': '"ABAB"'} "AB"
{'str1': '"LEET"', 'str2': '"CODE"'} ""
{'str1': '"ABCDEF"', 'str2': '"ABC"'} ""


'Accepted'

4.5 Programming Pitfalls

Trap 1: "" "doc" "", three pairs of double quotation marks contain quotation marks, if the quotation marks are not removed, it will be regarded as character content, resulting in the "failure" of the Solution algorithm.

doc = """ABC "efg" HIGK"""  # efg带引号
doc.split()                 # 分割后'"efg"'而不是'efg',不注意还看不出来

['ABC', '"efg"', 'HIGK']

Way to avoid pitfalls: .replace('"','') to remove content quotation marks

def get_test_cases(str_examples):
    import re
    params =re.split('Example.+?:',str_examples.replace('\n','').replace(' ',''))[1:]
    cases_arg, cases_ans = [], []
    for param in params:
        kawargs = {}
        args_,ans = param.split('Output:')
        args_ = args_.replace('Input:','').strip().split(',')
        # ans.replace('"','')
        cases_ans.append(ans.replace('"','')) 
        for arg in args_:
            key,val = arg.split("=")
             # val.replace('"','')
            kawargs[key] = val.replace('"','')
        cases_arg.append(kawargs)
    return zip(cases_arg, cases_ans)

Trap 2: try...except not only captures the success or failure of the assert assertion, but also prints (kawargs, answer) in try, and the wrong writing of 'kawargs' also leads to entering the except block.

Avoidance method: try...except Exception as e printing exception, debug error

# 捕获except异常并不等于assert断言失败
try:
    print(what)
    assert 1==1
except Exception as e:
    print(e)

name 'what' is not defined

def auto_test(test_cases):
    f = getattr(Solution(), dir(Solution())[-1])
    try:
        for kwargs, answer in test_cases:
            print(kwargs,answer)
            assert f(**kwargs) == answer        
        return 'Accepted'
    except Exception as e:  
        print(e)
        return 'Wrong Answer'

Ways to avoid pits: Fall into this pit for the first time, refresh zip cognition, and remember it.

4.6 Test again

test_cases = get_test_cases(str_Examples)
auto_test(test_cases)

{'str1': 'ABCABC', 'str2': 'ABC'} ABC
{'str1': 'ABABAB', 'str2': 'ABAB'} AB
{'str1': 'LEET', 'str2': 'CODE'} 
{'str1': 'ABCDEF', 'str2': 'ABC'} 

'Accepted'

auto_test(get_test_cases(str_Examples))

{'str1': 'ABCABC', 'str2': 'ABC'} ABC
{'str1': 'ABABAB', 'str2': 'ABAB'} AB
{'str1': 'LEET', 'str2': 'CODE'} 
{'str1': 'ABCDEF', 'str2': 'ABC'} 

'Accepted'

5. Summary

step1: Write LeetCode question answering code in Jupyter notebook

class Solution: def method(self,**kwargs):

step2: Copy the content of Example in LeetCode to the variable str_Examples
step3: Use get_test_cases to get test cases
step4: Call auto_test for automatic testing, return 'Accepted' for all test cases passed, 'Wrong Answer' indicates that there are test cases that failed.

All the Example tests in the LeetCode problem Description pass, that is, the Run Code result is 'Accepted', which does not mean that the result after Submit will be 'Accepted'. On the contrary, if the Run Code result is 'Wrong Answer', then the result after Submit must be 'Wrong Answer'. Because the Example in the Description is only a partial example, it is a subset of the test case collection verified after submitting.

def get_test_cases(str_examples):
    import re
    params =re.split('Example.+?:',str_examples.replace('\n','').replace(' ',''))[1:]
    cases_arg, cases_ans = [], []
    for param in params:
        kawargs = {}
        args_,ans = param.split('Output:')
        args_ = args_.replace('Input:','').strip().split(',')
        # ans.replace('"','')
        cases_ans.append(ans.replace('"','')) 
        for arg in args_:
            key,val = arg.split("=")
             # val.replace('"','')
            kawargs[key] = val.replace('"','')
        cases_arg.append(kawargs)
    return zip(cases_arg, cases_ans)

def auto_test(test_cases):
    f = getattr(Solution(), dir(Solution())[-1])
    try:
        for kwargs, answer in test_cases:
            print(kwargs,answer)
            assert f(**kwargs) == answer        
        return 'Accepted'
    except Exception as e:  
        print(e)
        return 'Wrong Answer'

Finally : In order to give back to the die-hard fans, I have compiled a complete software testing video learning tutorial for you. If you need it, you can get it for free【保证100%免费】

Software Testing Interview Documentation

We must study to find a high-paying job. The following interview questions are the latest interview materials from first-tier Internet companies such as Ali, Tencent, and Byte, and some Byte bosses have given authoritative answers. Finish this set The interview materials believe that everyone can find a satisfactory job.


How to obtain the full set of information:

insert image description here

Guess you like

Origin blog.csdn.net/weixin_56331124/article/details/131168642