Flask服务器的自动化测试无法识别渲染模板(Python)中的HTML标签

时间:2018-06-22 13:58:45

标签: python html flask

我真的是Stack Overflow的新手(对此通常进行编码)。我们在大学网络编程期间的最终任务是制造一个Flask服务器,该服务器将从openFDA API(商业药品标签的汇编)中恢复信息。它必须检索药品的名称/制造商/医疗警告...并将它们显示在HTML列表中,然后使用“ render_template”命令进行渲染。

服务器的代码将由老师给我们的程序进行测试,我们需要通过所有测试,以确保整个课程不会失败。目前,我只剩下三个测试需要击败,但我无法弄清楚。

我对发生的事情有一点了解。我认为测试无法识别列表元素的标签“ li”标签,因此认为列表只是空的。我已经尝试解决此问题,但到目前为止我还没有运气。

如果你们能在两天或更短的时间内给我解决方案,我将不胜感激。如果我不这样做,我将不得不为明年的学费支付大量资金,所以,是的...

这是我的服务器:

from flask import Flask
from flask import render_template
from flask import request
from flask import Response
from flask import redirect
from functools import wraps
import http.client
import json

app = Flask(__name__)

MAIN_INPUT = "api.fda.gov"
headers = {'User-Agent': 'http-client'}
DEBUG = True

main_conn = http.client.HTTPSConnection(MAIN_INPUT)

@app.route ("/searchDrug", methods = ['GET']) # Busca hasta 100 medicamentos con el principio activo especificado
def getActIng():

    name = request.args['active_ingredient']
    limit = request.args['limit']

    try:
        openfda_input = '/drug/label.json?search=active_ingredient:{acting}&limit={lim}'.format(acting=name,lim=limit)
        main_conn.request('GET', openfda_input, None, headers)
    except:
        print("Error")
        exit(1)

    data_stage1 = main_conn.getresponse()

    data_stage2 = data_stage1.read()
    main_conn.close()

    data_final = json.loads(data_stage2)

    main_dict = data_final['results']
    name_list=[]
    for elem in main_dict:
        if 'brand_name' in elem['openfda']:
            name_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
        else:
            name_list.append("<li>Desconocido</li>")

    name_str = str(''.join(name_list))

    def print_ul(elements):
        print("<ul>")
        for s in elements:
            ul = "<li>" + str(s) + "</li>"
        print(ul)
        print("</ul>")

    html_str = """
        <!DOCTYPE html>
        <html>
        <body>
        <p>Nombres comerciales disponibles para medicamentos con {r} como principio activo en openFDA:</p>
        <p>Mostrando {l} resultados</p>
        <ul>
        <p>{mans}</p>
        </ul>
        </body>
        </html>
        """

    with open("templates/getActIng.html","w") as main_output:
        main_output.write("")
        html_str_mod = html_str.format(r=name, l=limit, mans=name_str)
        main_output.write(html_str_mod)

    print(name_str)

    return render_template('getActIng.html')

@app.route ("/searchCompany", methods = ['GET']) # Busca hasta 100 medicamentos fabricados por la empresa especificada
def getComName():

    company_name = request.args['company']
    limit = request.args['limit']

    try:
        openfda_input = '/drug/label.json?search=manufacturer_name:{comnam}&limit={lim}'.format(comnam=company_name,lim=limit)
        main_conn.request('GET', openfda_input, None, headers)
    except:
        print("Error")
        exit(1)

    data_stage1 = main_conn.getresponse()

    data_stage2 = data_stage1.read()
    main_conn.close()

    data_final = json.loads(data_stage2)

    main_dict = data_final['results']
    med_list=[]
    for elem in main_dict:
        if 'manufacturer_name' in elem['openfda']:
            med_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
        else:
            med_list.append("<li>Desconocido</li>")

    med_str = str(''.join(med_list))

    html_str = """
        <!DOCTYPE html>
        <html>
        <body>
        <p>Medicamentos fabricados por {r} en openFDA:</p>
        <p>Mostrando {l} resultados</p>
        <ul>
        <p>{meds}</p>
        </ul>
        </body>
        </html>
        """

    with open("templates/getComName.html","w") as main_output:
        html_str_mod = html_str.format(r=company_name,l=limit,meds=med_str)
        main_output.write(html_str_mod)

    return render_template('getComName.html')

@app.route ("/listDrugs", methods = ['GET']) # Devuelve una cantidad aleatoria de medicamentos
def getListDrugs():

    limit = request.args['limit']

    try:
        openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
        main_conn.request('GET', openfda_input, None, headers)
    except:
        print("Error")
        exit(1)

    data_stage1 = main_conn.getresponse()

    data_stage2 = data_stage1.read()
    main_conn.close()

    data_final = json.loads(data_stage2)

    main_dict = data_final['results']
    ran_list=[]
    for elem in main_dict:
        if 'brand_name' in elem['openfda']:
            ran_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
        else:
            ran_list.append("<li>Desconocido</li>")

    ran_str = str(''.join(ran_list))

    html_str = """
        <!DOCTYPE html>
        <html>
        <body>
        <p>Nombres comerciales de {r} medicamentos de openFDA:</p>
        <p>Mostrando {l} resultados</p>
        <ul>
        <p>{rans}</p>
        </ul>
        </body>
        </html>
        """

    with open("templates/getListDrugs.html","w") as main_output:
        html_str_mod = html_str.format(r=limit,l=limit, rans=ran_str)
        main_output.write(html_str_mod)

    return render_template('getListDrugs.html')

@app.route ("/listCompanies", methods = ['GET']) # Devuelve una cantidad especificada de empresas con uno de sus productos
def getListCom():

    limit = request.args['limit']

    try:
        openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
        main_conn.request('GET', openfda_input, None, headers)
    except:
        print("Error")
        exit(1)

    data_stage1 = main_conn.getresponse()

    data_stage2 = data_stage1.read()
    main_conn.close()

    data_final = json.loads(data_stage2)

    main_dict = data_final['results']
    com_list=[]
    for elem in main_dict:
        if 'manufacturer_name' in elem['openfda']:
            com_list.append("<li>" + str(elem['openfda']['manufacturer_name']).strip("['']") + "</li>")
        else:
            com_list.append("<li>Desconocido</li>")

    com_str = str(''.join(com_list))

    html_str = """
        <!DOCTYPE html>
        <html>
        <body>
        <p>Nombres de {r} fabricantes (y sus respectivos productos) de openFDA:</p>
        <p>Mostrando {l} resultados</p>
        <ul>
        <p>{prod}</p>
        </ul>
        </body>
        </html>
        """

    with open("templates/getListCom.html","w") as main_output:
        html_str_mod = html_str.format(r=limit,l=limit, prod=com_str)
        main_output.write(html_str_mod)

    return render_template('getListCom.html')

@app.route ("/listWarnings", methods = ['GET']) # Devuelve una cantidad aleatoria de medicamentos
def getListWar():

    limit = request.args['limit']

    try:
        openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
        main_conn.request('GET', openfda_input, None, headers)
    except:
        print("Error")
        exit(1)

    data_stage1 = main_conn.getresponse()

    data_stage2 = data_stage1.read()
    main_conn.close()

    data_final = json.loads(data_stage2)

    main_dict = data_final['results']
    war_list=[]
    for elem in main_dict:
        if 'warnings' in elem:
            war_list.append("<li>" + str(elem['warnings']).strip("['']") + "</li>")
        else:
            war_list.append("<li>Desconocido</li>")

    war_str = str(''.join(war_list))

    html_str = """
        <!DOCTYPE html>
        <html>
        <body>
        <p>Advertencias:</p>
        <p>Mostrando {l} resultados</p>
        <ul>
        <p>{wars}</p>
        </ul>
        </body>
        </html>
        """

    with open("templates/getListWars.html","w") as main_output:
        html_str_mod = html_str.format(l=limit, wars=war_str)
        main_output.write(html_str_mod)

    return render_template('getListWars.html')

@app.route('/secret', methods = ['GET'])
def getSecret():
    return Response(
    'Could not verify your access level for that URL.\n'
    'You have to login with proper credentials', 401,
    {'WWW-Authenticate': 'Basic realm="Not Authorized"'})

@app.route('/redirect', methods = ['GET'])
def getRedirect():
    return redirect("http://127.0.0.1:8000/", code=302)

@app.route('/', methods=['GET', 'POST'])
def index():

    return """
        <!DOCTYPE html>
        <html lang="es">
        <head>
            <meta charset="UTF-8">
            <title>OpenFDA-project</title>
        </head>
        <body>
        <form action = "listDrugs" method="get">
          <input type="submit" value="Listar fármacos">
            Limite: <input type="text" name="limit" value="">
        </form>
        <form action = "listCompanies" method="get">
          <input type="submit" value="Listar empresas">
            Limite: <input type="text" name="limit" value="">
        </form>
        <form action = "searchDrug" method="get">
          <input type="submit" value="Buscar fármaco">
            Campo: <input type="text" name="active_ingredient" value="">
            Limite Drug: <input type="text" name="limit" value="">
        </form>
        <form action = "searchCompany" method="get">
          <input type="submit" value="Buscar empresas">
            Campo: <input type="text" name="company" value="">
            Limite Com: <input type="text" name="limit" value="">
        </form>
        <form action = "listWarnings" method="get">
          <input type="submit" value="Advertencias">
            Limite: <input type="text" name="limit" value="">
        </form>
        </body>
        </html>
        """

if __name__ == "__main__":
    app.run('127.0.0.1', port = 8000, debug = True, use_reloader = False)

这是自动测试:

import os
import subprocess
import sys
import threading
import time
import unittest

import requests

from html.parser import HTMLParser

PYTHON_CMD = os.path.abspath(sys.executable)

class OpenFDAHTMLParser(HTMLParser):

    def __init__(self):
        super().__init__()
        self.actions_list = []
        self.forms_number = 0
        self.items_number = 0

    def handle_starttag(self, tag, attrs):
        # print("Encountered a start tag:", tag)
        if tag == "form":
            self.forms_number += 1
            for attr in attrs:
                if attr[0] == 'action':
                    self.actions_list.append(attr[1])
        elif tag == "li":
            self.items_number += 1


    def handle_endtag(self, tag):
        # print("Encountered an end tag :", tag)
        pass


    def handle_data(self, data):
        # print("Encountered some data  :", data)
        pass


class WebServer(threading.Thread):
    """ Thread to start the web server """

    def run(self):
        # Start the web server in a thread. It will be killed once tests have finished
        cmd = [PYTHON_CMD, 'server.py']
        proc = subprocess.Popen(cmd, stderr=subprocess.PIPE)
        TestOpenFDA.WEBSERVER_PROC = proc
        outs, errs = proc.communicate()
        errs_str = errs.decode("utf8")
        if 'Address already in use' in errs_str:
            TestOpenFDA.PORT_BUSY = True
            return

class TestOpenFDA(unittest.TestCase):
    """ Automatic testing for OpenFDA web server main features """
    WEBSERVER_PROC = None
    PORT_BUSY = False
    TEST_PORT = 8000
    TEST_DRUG = 'Aspirin'
    TEST_COMPANY = 'Bayer'
    TEST_ACTIONS = ['listDrugs', 'searchDrug', 'listCompanies', 'searchCompany', 'listWarnings']

    @classmethod
    def setUpClass(cls):
        """ Start the web server to be tested """
        WebServer().start()
        # Wait for web sever init code
        time.sleep(1)
        if cls.PORT_BUSY:
            raise RuntimeError("PORT BUSY")

    @classmethod
    def tearDownClass(cls):
        """ Shutdown the webserver """
        cls.WEBSERVER_PROC.kill()

    def test_web_server_init(self):
        resp = requests.get('http://localhost:' + str(self.TEST_PORT))
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        # Remove listWarnings that it is not in the basic specification
        self.TEST_ACTIONS.remove('listWarnings')
        try:
            parser.actions_list.remove('listWarnings')
        except ValueError:
            # The form does not include this option
            pass
        self.assertEqual(len(parser.actions_list), 4)
        self.assertEqual(set(self.TEST_ACTIONS), set(parser.actions_list))
        self.TEST_ACTIONS.append('listWarnings')

    def test_web_server_init_warnings(self):
        # In the complete project a listWarnings is included
        resp = requests.get('http://localhost:' + str(self.TEST_PORT))
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.forms_number, 5)
        self.assertEqual(set(self.TEST_ACTIONS), set(parser.actions_list))

    def test_list_drugs(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/listDrugs?limit=10'
        resp = requests.get(url)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 10)

    def test_list_drugs_limit(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/listDrugs?limit=22'
        resp = requests.get(url)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 22)

    def test_search_drug(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/searchDrug?active_ingredient="%s"' % self.TEST_DRUG
        resp = requests.get(url)
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 10)

    def test_list_companies(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/listCompanies?limit=10'
        resp = requests.get(url)
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 10)

    def test_list_warnings(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/listWarnings?limit=10'
        resp = requests.get(url)
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 10)

    def test_search_company(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/searchCompany?company=' + self.TEST_COMPANY
        resp = requests.get(url)
        # print(resp.text)
        parser = OpenFDAHTMLParser()
        parser.feed(resp.text)
        self.assertEqual(parser.items_number, 10)

    def test_not_found(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/not_exists_resource'
        resp = requests.get(url)
        self.assertEqual(resp.status_code, 404)

    def test_redirect(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/redirect'
        resp = requests.get(url)
        self.assertEqual(resp.status_code, 200)

    def test_auth(self):
        url = 'http://localhost:' + str(self.TEST_PORT)
        url += '/secret'
        resp = requests.get(url)
        self.assertEqual(resp.status_code, 401)


if __name__ == "__main__":
    unittest.main(warnings='ignore')

这是我在Windows命令提示符中获得的追溯信息(我知道,我知道,在获得新的硬盘XD之后,我将切换到一些Linux发行版):

https://imgur.com/4YvSEvR

0 个答案:

没有答案