Test fails in tests.py but succeeds in python shell - django-testing

I'm a newbee to python and django and I can't figure out what I'm doing wrong here.
I have a Site object:
class Site (models.Model):
domain = models.CharField(max_length=30)
support_status = models.CharField(max_length=20, choices= SITE_SUPPORTED_STATUS, blank=False)
requests = models.IntegerField()
objects = SiteManager()
def __unicode__(self):
return u'%s %s' % (self.domain, self.support_status)
And a SiteManager object
class SiteManager(models.Manager):
def supported_site_counts(self):
i = self.filter(support_status__iexact="SUPPORTED").count()
return i
From the console, the method "supported_site_counts()" works just fine
>>(InteractiveConsole)
>>> from bookmark.models import Site, SiteManager
>>> Site.objects.supported_site_counts()
>>>>2012-05-18 18:09:20,027 DEBUG (0.001) SELECT COUNT(*) FROM "bookmark_site" WHERE
>>>>"bookmark_site"."support_status" LIKE SUPPORTED ESCAPE '\' ; args=(u'SUPPORTED',)
>>>>2012-05-18 18:09:20,028 DEBUG Got 1 supported site
>>>>1
But when it's called from a testcase, the count returns as 0
class SiteManagerTest(unittest.TestCase):
def test_supported_site_counts(self):
self.x = False
self.count = Site.objects.supported_site_counts()
logging.debug(self.count)

This is probably because the tests will set up a database separate from your development database to run the tests in. You will need to put testing data in to the testing database, either programmatically or using fixtures.

Related

How to create a fake StringSession for unit tests

I've got some code which uses StringSession to talk to the Telegram API using telethon.
In my unit tests, I'm trying to instantiate a mocked TelegramClient, passing it a StringSession(myvalue) object as the first parameter. The real code works fine, but I need a fake session string for 'myvalue', to use in my unit tests (where I have a mocked telegram client).
How can I create a dummy value for 'myvalue' which will successfully execute StringSession(myvalue)?
Currently, my tests are dying here:
self = <telethon.sessions.string.StringSession object at 0x7f0777492ad0>
string = 'dummyxxx'
def __init__(self, string: str = None):
super().__init__()
if string:
if string[0] != CURRENT_VERSION:
raise ValueError('Not a valid string')
string = string[1:]
ip_len = 4 if len(string) == 352 else 16
> self._dc_id, ip, self._port, key = struct.unpack(
_STRUCT_PREFORMAT.format(ip_len), StringSession.decode(string))
E struct.error: unpack requires a buffer of 275 bytes
If you don't need a valid session to start with, you can also use MemorySession instead:
from telethon.sessions import MemorySession
session = MemorySession()
# use session variable when creating the client
Someone posted an answer which helped point me in the right direction, but they later deleted it for some reason.
In case it helps anyone else, here is the code that worked for me:
import struct
import base64
from telethon.sessions import StringSession
_STRUCT_PREFORMAT = '>B{}sH256s'
CURRENT_VERSION = '1'
dc_id = 1
ip = b'\x7f\x00\x00\x01' # 127.0.0.1
port = 80
key = b'\x00' * 256
string = StringSession.encode(struct.pack(
_STRUCT_PREFORMAT.format(len(ip)),
dc_id,
ip,
port,
key
))
myvalue = CURRENT_VERSION + string
# Create the StringSession object using the dummy value to confirm it works
session = StringSession(myvalue)
print(myvalue)

how to read the console output in python without executing any command

I have an API which gets the success or error message on console.I am new to python and trying to read the response. Google throws so many examples to use subprocess but I dont want to run,call any command or sub process. I just want to read the output after below API call.
This is the response in console when success
17:50:52 | Logged in!!
This is the github link for the sdk and documentation
https://github.com/5paisa/py5paisa
This is the code
from py5paisa import FivePaisaClient
email = "myemailid#gmail.com"
pw = "mypassword"
dob = "mydateofbirth"
cred={
"APP_NAME":"app-name",
"APP_SOURCE":"app-src",
"USER_ID":"user-id",
"PASSWORD":"pw",
"USER_KEY":"user-key",
"ENCRYPTION_KEY":"enc-key"
}
client = FivePaisaClient(email=email, passwd=pw, dob=dob,cred=cred)
client.login()
In general it is bad practice to get a value from STDOUT. There are some ways but it's pretty tricky (it's not made for it). And the problem doesn't come from you but from the API which is wrongly designed, it should return a value e.g. True or False (at least) to tell you if you logged in, and they don't do it.
So, according to their documentation it is not possible to know if you're logged in, but you may be able to see if you're logged in by checking the attribute client_code in the client object.
If client.client_code is equal to something then it should be logged in and if it is equal to something else then not. You can try comparing it's value when you successfully login or when it fails (wrong credential for instance). Then you can put a condition : if it is None or False or 0 (you will have to see this by yourself) then it is failed.
Can you try doing the following with a successful and failed login:
client.login()
print(client.client_code)
Source of the API:
# Login function :
# (...)
message = res["body"]["Message"]
if message == "":
log_response("Logged in!!")
else:
log_response(message)
self._set_client_code(res["body"]["ClientCode"])
# (...)
# _set_client_code function :
def _set_client_code(self, client_code):
try:
self.client_code = client_code # <<<< That's what we want
except Exception as e:
log_response(e)
Since this questions asks how to capture "stdout" one way you can accomplish this is to intercept the log message before it hits stdout.
The minimum code to capture a log message within a Python script looks this:
#!/usr/bin/env python3
import logging
logger = logging.getLogger(__name__)
class RequestHandler(logging.Handler):
def emit(self, record):
if record.getMessage().startswith("Hello"):
print("hello detected")
handler = RequestHandler()
logger.addHandler(handler)
logger.warning("Hello world")
Putting it all together you may be able to do something like this:
import logging
from py5paisa import FivePaisaClient
email = "myemailid#gmail.com"
pw = "mypassword"
dob = "mydateofbirth"
cred={
"APP_NAME":"app-name",
"APP_SOURCE":"app-src",
"USER_ID":"user-id",
"PASSWORD":"pw",
"USER_KEY":"user-key",
"ENCRYPTION_KEY":"enc-key"
}
client = FivePaisaClient(email=email, passwd=pw, dob=dob,cred=cred)
class PaisaClient(logging.Handler):
def __init__():
self.loggedin = False # this is the variable we can use to see if we are "logged in"
def emit(self, record):
if record.getMessage().startswith("Logged in!!")
self.loggedin = True
def login():
client.login()
logging.getLogger(py5paisa) # get the logger for the py5paisa library
# tutorial here: https://betterstack.com/community/questions/how-to-disable-logging-from-python-request-library/
logging.basicConfig(handlers=[PaisaClient()], level=0, force=True)
c = PaisaClient()
c.login()

How to extract the [Documentation] text from Robot framework test case

I am trying to extract the content of the [Documentation] section as a string for comparision with other part in a Python script.
I was told to use Robot framework API https://robot-framework.readthedocs.io/en/stable/
to extract but I have no idea how.
However, I am required to work with version 3.1.2
Example:
*** Test Cases ***
ATC Verify that Sensor Battery can enable and disable manufacturing mode
[Documentation] E1: This is the description of the test 1
... E2: This is the description of the test 2
[Tags] E1 TRACE{Trace_of_E1}
... E2 TRACE{Trace_of_E2}
Extract the string as
E1: This is the description of the test 1
E2: This is the description of the test 2
Have a look at these examples. I did something similar to generate testplans descritio. I tried to adapt my code to your requirements and this could maybe work for you.
import os
import re
from robot.api.parsing import (
get_model, get_tokens, Documentation, EmptyLine, KeywordCall,
ModelVisitor, Token
)
class RobotParser(ModelVisitor):
def __init__(self):
# Create object with remarkup_text to store formated documentation
self.text = ''
def get_text(self):
return self.text
def visit_TestCase(self, node):
# The matched `TestCase` node is a block with `header` and
# `body` attributes. `header` is a statement with familiar
# `get_token` and `get_value` methods for getting certain
# tokens or their value.
for keyword in node.body:
# skip empty lines
if keyword.get_value(Token.DOCUMENTATION) == None:
continue
self.text += keyword.get_value(Token.ARGUMENT)
def visit_Documentation(self,node):
# The matched "Documentation" node with value
self.remarkup_text += node.value + self.new_line
def visit_File(self, node):
# Call `generic_visit` to visit also child nodes.
return self.generic_visit(node)
if __name__ == "__main__":
path = "../tests"
for filename in os.listdir(path):
if re.match(".*\.robot", filename):
model = get_model(os.path.join(path, filename))
robot_parser = RobotParser()
robot_parser.visit(model)
text=robot_parser._text()
The code marked as best answer didn't quite work for me and has a lot of redundancy but it inspired me enough to get into the parsing and write it in a much readable and efficient way that actually works as is. You just have to have your own way of generating & iterating through filesystem where you call the get_robot_metadata(filepath) function.
from robot.api.parsing import (get_model, ModelVisitor, Token)
class RobotParser(ModelVisitor):
def __init__(self):
self.testcases = {}
def visit_TestCase(self, node):
testcasename = (node.header.name)
self.testcases[testcasename] = {}
for section in node.body:
if section.get_value(Token.DOCUMENTATION) != None:
documentation = section.value
self.testcases[testcasename]['Documentation'] = documentation
elif section.get_value(Token.TAGS) != None:
tags = section.values
self.testcases[testcasename]['Tags'] = tags
def get_testcases(self):
return self.testcases
def get_robot_metadata(filepath):
if filepath.endswith('.robot'):
robot_parser = RobotParser()
model = get_model(filepath)
robot_parser.visit(model)
metadata = robot_parser.get_testcases()
return metadata
This function will be able to extract the [Documentation] section from the testcase:
def documentation_extractor(testcase):
documentation = []
for setting in testcase.settings:
if len(setting) > 2 and setting[1].lower() == "[documentation]":
for doc in setting[2:]:
if doc.startswith("#"):
# the start of a comment, so skip rest of the line
break
documentation.append(doc)
break
return "\n".join(documentation)

SoapUI API - Setting TestCase property

I'm trying to use SoapUI API in jython (modifying SoapUILibrary for Robot Framework) and somehow i am not able to find any way to set property of a Property TestStep.
Setting project, global and system properties is easy using
SoapUITestCaseRunner.setProjectProperties()
from com.eviware.soapui.tools import (SoapUITestCaseRunner)
from com.eviware.soapui.tools import (SoapUIMockServiceRunner)
from robot.api import logger
class SoapUILibrary2:
""" The main class of the library """
ROBOT_LIBRARY_SCOPE = 'TEST CASE'
ROBOT_LIBRARY_VERSION = '0.2'
def __init__(self):
self.__runner = None
self.__mockrunner = None
self._project_properties = []
def soapui_project(self, prj):
""" Initialize the runner and set the project string """
self.__runner = SoapUITestCaseRunner()
self.__runner.setProjectFile(prj)
def soapui_suite(self, s):
""" Set the suite string """
self.__runner.setTestSuite(s)
def soapui_case(self, c):
""" Set the test case string """
self.__runner.setTestCase(c)
def soapui_set_project_property(self, *properties):
""" Sets project properties for the current test run. (...)
"""
for prop in properties:
if len(prop.split('=')) == 2:
self._project_properties.append(prop)
else:
logger.warn("Skipping property: '%s'. Properties must be specified as: key=value" % prop)
try:
self.__runner.setProjectProperties(self._project_properties)
except AttributeError:
logger.warn('No project set. Cannot set project properties.')
SoapUITestCaseRunner class does not contain any way to access testSteps...
I found some examples how to solve this issue in groovy, however is it possible to set such properties using SoapUI API?
EDIT:
Adding whole code of the library. It's made to be imported in robot framework and used as its keywords.
http://tny.cz/34882261
In SOAPUI you can define properties for project, testCase and testSuite, it's also possible to generate a special type of testStep (Properties TestStep) but you can't define properties on a specific testStep (i.e on SOAP TestStep). You can see more info about here
However you can use a properties from project, testCase or testSuite in your testSteps so i.e you can define a property in a project level and then use it in your testStep. I can't give more specific info because I don't know exactly what you're trying to achieve.
EDIT:
I don't know the specific jython syntax but If you have the project file (as I see in your sample) you can access a specific testStep through com.eviware.soapui.impl.wsdl.WsdlProject, I give you a groovy script as example:
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep
def prj = new WsdlProject(path_prj_file,null);
def tsuite = prj.getTestSuiteByName("TestSuiteName");
def tcase = tsuite.getTestCaseByName("TestCaseName");
def tstep = tcase.getTestStepByName("TestStep");
EDIT 2:
I download jython standalone version 2.5.3 and use soapui 5.0.0 and works for me:
hw.py
from com.eviware.soapui.tools import (SoapUITestCaseRunner)
from com.eviware.soapui.tools import (SoapUILoadTestRunner)
from com.eviware.soapui.tools import (SoapUIMockServiceRunner)
from com.eviware.soapui.impl.wsdl import (WsdlProject)
from com.eviware.soapui.impl.wsdl import (WsdlTestSuite)
from com.eviware.soapui.impl.wsdl.testcase import (WsdlTestCase)
from com.eviware.soapui.impl.wsdl.teststeps import (WsdlTestRequestStep)
import thread
class SoapUI2:
""" The main class of the library """
ROBOT_LIBRARY_SCOPE = 'TEST CASE'
ROBOT_LIBRARY_VERSION = '0.2'
def __init__(self):
self.__runner = None
self.__mockrunner = None
self._project_properties = []
self.__prj = WsdlProject('C:\soapui_project.xml', None)
self.__tsuite = self.__prj.getTestSuiteByName("myTestSuite")
self.__tcase = self.__tsuite.getTestCaseByName("myTestCase")
self.__tstep = self.__tcase.getTestStepByName("myTestStep")
t = self.__tstep.getPropertyValue("Value")
print "Works ok"
def soapui_project(self, prj):
""" Initialize the runner and set the project string """
self.__runner = SoapUITestCaseRunner()
self.__runner.setProjectFile(prj)
def soapui_multiproject(self, prj):
""" Initialize the runner and set the project string """
self.__runner = SoapUILoadTestRunner()
self.__runner.setProjectFile(prj)
def soapui_suite(self, s):
""" Set the suite string """
self.__runner.setTestSuite(s)
def soapui_case(self, c):
""" Set the test case string """
self.__runner.setTestCase(c)
def soapui_set_project_property(self, *properties):
""" Sets project properties for the current test run.
This assumes that you have already initialized the project via
the `SoapUI Project` keyword.
`properies` may contain multiple statements, and each must be specified as: key=value.
This is useful to data drive your existing SoapUI tests via property expansion.
For more information see: http://www.soapui.org/Scripting-Properties/property-expansion.html
Example:
| SoapUI Project | My Project |
| SoapUI Set Project Property | ServiceEndpoint=https://staging.company.com | # set a single property |
| SoapUI Set Project Property | CustomProperty=foo | AnotherProperty=bar | # or set multiple properties |
"""
for prop in properties:
if len(prop.split('=')) == 2:
self._project_properties.append(prop)
else:
logger.warn("Skipping property: '%s'. Properties must be specified as: key=value" % prop)
try:
self.__runner.setProjectProperties(self._project_properties)
except AttributeError:
logger.warn('No project set. Cannot set project properties.')
def soapui_set_multiproject_threads(self, t):
""" Sets number of threads to run in load test """
self.__runner.setThreadCount(long(t))
logger.info("Running with %s threads at once." % t)
def soapui_run(self):
""" Run the runner and report to Robot """
logger.info("Running with the following project properties set: %s" % self._project_properties)
if not self.__runner.run():
raise AssertionError('FAIL: failed to run')
if self.__runner == SoapUITestCaseRunner():
n = self.__runner.getFailedTests().size()
if n != 0:
raise AssertionError('FAIL: ' + str(n) + ' tests failed')
def soapui_start_mock_service(self, p, m):
""" Runs a mock service """
try:
self.__mockrunner = SoapUIMockServiceRunner()
self.__mockrunner.setProjectFile(p)
self.__mockrunner.setMockService(m)
self.__mockrunner.setBlock(False)
self.__mockrunner.run()
except Exception, e:
raise AssertionError('FAIL: Error running the mock service ' + m + '. Reason: ' + str(e))
def soapui_stop_mock_service(self):
""" Stops the mock service """
self.__mockrunner.stopAll()
def soapui_set_step_property(self, s, p,v):
testStep = self.__runner.testCase.getTestStepByName(s)
testStep.setPropertyValue(p,v)
if __name__ == "__main__":
SoapUI2().__init__()
cmd line execution:
java -classpath "jython-standalone-2.5.3.jar;C:\Programari\SoapUI-5.0.0\lib\*;C:\Programari\SoapUI-5.0.0\bin\*" org.python.util.jython hw.py
execution result:
2014-05-27 12:43:09,058 [main] WARN com.eviware.soapui.SoapUI - Could not find jfxrt.jar. Internal browser will be disabled.
12:43:09,589 WARN [SoapUI] Missing folder [C:\temp\ext] for external libraries
12:43:09,964 INFO [DefaultSoapUICore] initialized soapui-settings from [C:\Documents and Settings\aciffone\soapui-settings.xml]
12:43:09,995 INFO [HttpClientSupport$Helper] Initializing KeyStore
12:43:11,682 INFO [WsdlProject] Loaded project from [file:/C:/soapui_project.xml]
Works ok
Hope this helps,

Advice needed on setting up an (Objective C?) Mac-based web service

I have developed numerous iOS apps over the years so know Objective C reasonably well.
I'd like to build my first web service to offload some of the most processor intensive functions.
I'm leaning towards using my Mac as the server, which comes with Apache. I have configured this and it appears to be working as it should (I can type the Mac's IP address and receive a confirmation).
Now I'm trying to decide on how to build the server-side web service, which is totally new to me. I'd like to leverage my Objective C knowledge if possible. I think I'm looking for an Objective C-compatible web service engine and some examples how to connect it to browsers and mobile interfaces. I was leaning towards using Amazon's SimpleDB as the database.
BTW: I see Apple have Lion Server, but I cannot work out if this is an option.
Any thoughts/recommendations are appreciated.?
There are examples of simple web servers out there written in ObjC such as this and this.
That said, there are probably "better" ways of doing this if you don't mind using other technologies. This is a matter of preference; but I've use Python, MySQL, and the excellent web.py framework for these sorts of backends.
For example, here's an example web service (some redundancies omitted...) using the combination of technologies described. I just run this on my server, and it takes care of url redirection and serves JSON from the db.
import web
import json
import MySQLdb
urls = (
"/equip/gruppo", "gruppo", # GET = get all gruppos, # POST = save gruppo
"/equip/frame", "frame"
)
class StatusCode:
(Success,SuccessNoRows,FailConnect,FailQuery,FailMissingParam,FailOther) = range(6);
# top-level class that handles db interaction
class APIObject:
def __init__(self):
self.object_dict = {} # top-level dictionary to be turned into JSON
self.rows = []
self.cursor = ""
self.conn = ""
def dbConnect(self):
try:
self.conn = MySQLdb.connect( host = 'localhost', user = 'my_api_user', passwd = 'api_user_pw', db = 'my_db')
self.cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
except:
self.object_dict['api_status'] = StatusCode.FailConnect
return False
else:
return True
def queryExecute(self,query):
try:
self.cursor.execute(query)
self.rows = self.cursor.fetchall()
except:
self.object_dict['api_status'] = StatusCode.FailQuery
return False
else:
return True
class gruppo(APIObject):
def GET(self):
web.header('Content-Type', 'application/json')
if self.dbConnect() == False:
return json.dumps(self.object_dict,sort_keys=True, indent=4)
else:
if self.queryExecute("SELECT * FROM gruppos") == False:
return json.dumps(self.object_dict,sort_keys=True, indent=4)
else:
self.object_dict['api_status'] = StatusCode.SuccessNoRows if self.rows.count == 0 else StatusCode.Success
data_list = []
for row in self.rows:
# create a dictionary with the required elements
d = {}
d['id'] = row['id']
d['maker'] = row['maker_name']
d['type'] = row['type_name']
# append to the object list
data_list.append(d)
self.object_dict['data'] = data_list
# return to the client
return json.dumps(self.object_dict,sort_keys=True, indent=4)