2

I am writting unit tests for a flask app. This app expose REST endpoints and uses the flask_restful lib.

Basically, one of my endpoints will do requests to other endpoints and do some processing.

While executing the tests through pytest, it returns this error (NOTE: this works when basically testing with curl) :

   requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', 
   port=5000): Max retries exceeded with url: 
   /ctrlm/H_INFOEXPLH:05u3v/output/ 
   (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object 
   at 
   0x0486D090>: Failed to establish a new connection: [WinError 10061]

Here is the test code :

class RestTests(unittest.TestCase):
""" Test the rest module. """
    ############################
    #### setup and teardown ####
    ############################

    def setUp(self):
        """ Executed prior to each test """
        app.config['TESTING'] = True
        app.config['WTF_CSRF_ENABLED'] = False
        app.config['DEBUG'] = False
        app.config['THREADED'] = True

        self.client = app.test_client()

        # incident id:
        self.incident = "INC1863137"

        # ctrl-m job id :
        self.jobid_no_output = "server:0ceit"
        self.jobid_no_job = "server:0ceity"  # job format that will surely fail!

    def tearDown(self):
        """ executed after each testexecuted after each test """
        pass

    ###############
    #### tests ####
    ###############

    def test_ctrl_output(self):
        """ UAT 3 : ctrl-M job output is found. """
        response = self.client.post('/servnow/incident/{}'.format(self.incident),
                                data=json.dumps({'data': "This is just a json test"}),
                                headers={'Content-Type': 'application/json'}
                                )
        #print("DEBUGGGG!!!!!!!!!!!!!!!!!!! ===============> {}".format(response))
        self.assertIsNotNone(response)

Well, maybe the flask instance initiated with setUp() is not able to be threaded...

On the app code, this is this code which create the issue :

    url = "http://127.0.0.1:5000{}".format(
        flask.url_for('joboutput', jobid=jobid))
    resp = requests.get(url).json()

Well, I just would like to execute a query to an url from flask... Probably, I'm doing it the wrong way....

Could you help me, please?

stockersky
  • 1,531
  • 2
  • 20
  • 36
  • the error raised by requests which is not used by flask test client, it is an error side your app. – georgexsh Oct 17 '17 at 15:06
  • Yes, I use requests to execute a request on another endpoint. Then process the response before returning. Flask has 'redirect' but every examples i read use it as a return instruction. – stockersky Oct 17 '17 at 15:21
  • not clear what you saying... – georgexsh Oct 17 '17 at 15:22
  • I use this in my code : 'resp = requests.get(url).json()' (with url formated like 127.0.0.1:5000:/etc/etc). But, if i use something like 'resp = flask.redirect(flask.url_for('joboutput', jobid=jobid))', resp.data is a string 'b' \nRedirecting...\n

    Redirecting...

    \n

    You should be redirected automatically to target URL: /ctrlm/H_INFOEXPLH:05u3v/output/. If not click the link.'

    – stockersky Oct 17 '17 at 16:00
  • you requested an URL with 'requests', it returned an error, I see there is nothing to with flask. – georgexsh Oct 17 '17 at 19:48
  • My flask app exposes several REST endpoints. One of those endpoint makes a query with requests on another endpoint. This target REST url is on the same flask test instance generated by the unittest setUp(). You can read it in the error message.But somewhere, this flask test instance refuses to establish the connection. This can happen when flask server is not called with the argument 'threaded=True'. But I don't know how to call a flask test instance (generated by unittest setUp()) with threaded mode enabled. This actually works when I lauch the flask server. but not in a unittest context. – stockersky Oct 17 '17 at 22:24
  • I have red several examples where a flask REST endpoint uses requests to call another url. But maybe, those target url aren't served by the same flask instance... – stockersky Oct 17 '17 at 22:29
  • flask test_client don't use network stack, it called WSGI interface of the app instance directly, your requests lib make a call to an HTTP endpoint doesn't exists in unitest. if you start a flask test server, I think you are doing it wrong. – georgexsh Oct 18 '17 at 18:24
  • Thanks Georgexsh! That's the explanation! – stockersky Oct 19 '17 at 11:47
  • I'm glad it helped. – georgexsh Oct 21 '17 at 10:01

1 Answers1

0

Unittest's Flask test server is a kind of a mock. It does not create listening socket.

So, making a request to itself is not possible.

Therefore :

url = "http://127.0.0.1:5000{}".format(
    flask.url_for('joboutput', jobid=jobid))
resp = requests.get(url).json()

will end in the aforementioned exception :

requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', 
port=5000)
Failed to establish a new connection

socket 127.0.0.1:5000 is just not created.

Well, it also made me think that the solution i'm building is not right if I cannot test it. I have rebuilded it.

stockersky
  • 1,531
  • 2
  • 20
  • 36
  • @Miguel Hello Miguel, I have seen from your profile that you're really into Flask and already answered questions close from mine... I would like to be sure that there isn't any other way to test case where flask issues a request on its own socket. Thanks. – stockersky Oct 31 '17 at 15:32