?????????????????
??????????????????????case??????????????????QC???????????????????????????case???????????????????????????????????????????????????????????????????QC???????????????????????????????????????????????????????????????
??????????д???С?????????????
?????·?????????hp????ALM Rest api???????????????????????http???????????????????????????????????QC test instance???
??????????????
????requests????????http????
????BeautifulSoup4?????????QC????????????????
??????????????????
???????崠?????£?
????????????????QC
[2017-05-17 13:57:25??023] Starting new HTTP connection (1): XXXXX.com
[2017-05-17 13:57:25??430] post http://XXXXX.com:80/qcbin/authentication-point/authenticate
[2017-05-17 13:57:25??430] headers = {'Authorization': 'Basic XXXXXXX'}
[2017-05-17 13:57:25??430] 200 OK
[2017-05-17 13:57:25??430] --------------------?????????????????
???????????????????????????????log????????????????????????Щ?????
???????????????????test_set_id?QC????????????test set?μ?test instance????Щ??
[2017-05-17 13:57:25??430] --------------------
[2017-05-17 13:57:26??303] get http://XXXXX.com:80/qcbin/rest/domains/??Domain name??/projects/??Project name??/test-instances?query={contains-test-set.id[XXXXXX]}&fields=id??test-id&page-size=2000
[2017-05-17 13:57:26??303] 200 OK
[2017-05-17 13:57:26??303] --------------------
??????????test instance id??????qc??????test id???????????????id??????????id????qc???????????????????
???????????????????????????????????????????????test set id?μ?test-instance?????????????????test instance id?? test id
test-instances?query={contains-test-set.id[XXX]}&fields=id??test-id&page-size=2000
[2017-05-17 13:57:26??303] --------------------
[2017-05-17 13:57:26??516] get http://XXXXX.com:80/qcbin/rest/domains/XXX/projects/XXX/tests?query={id[XXXXXX]}&fields=name&page-size=2000
[2017-05-17 13:57:26??516] 200 OK
[2017-05-17 13:57:26??516] --------------------
??????????????????test-id??β??????????test??name????
??????????????????????????????????????????????????????????????????????????????????????????test-instance???
?????????????????????????????requests????
????data = {
????'filename': (""?? attachment_name)??
????            'override-existing-attachment':(""??"y")
????        }
????file = {
????'file': open(attachmentpath+attachment_name?? 'rb')
????        }
????response = self.session.post(url?? files=file??data=data)
?????????Щ???????ο???
?????????????????get?????post??????auto_log???????????????????log??
?????????ЩQC???????????????????log
????import logging as log
????import requests
????class RestClient:
????    def __init__(self):
????        self.headers={}
????        self.session = requests.Session()
????        log.basicConfig(level=log.INFO?? format='[%(asctime)s] %(message)s')
????    def auto_log(func):
????        def wrapper(*args?? **kw):
????            r = func(*args?? **kw)
????            log.info("%s %s"?? func.func_name?? args[1])
????            for key in kw:
????                log.info("%s = %s"??key?? kw[key])
????            log.info("%s %s"??r.status_code??r.reason)
????            log.info("--------------------")
????            return r
????        return wrapper
????    @auto_log
????    def get(self?? url):
????        return self.session.get(url)
????    @auto_log
????    def post(self?? url?? files=None?? data=None??headers=None):
????        if headers is None:
????            headers = self.headers
????        return self.session.post(url?? headers=headers??files=files??data=data)
?????????????????????QC?????????????????????????entity???????????????????????????????entity?????entity?????ο???????common tasks???????????????
??class QCSession:
????    def __init__(self?? username?? password?? qc_url):
????        self.api_client=RestClient()
????        auth = base64.b64encode("{}:{}".format(username?? password))
????        self.api_client.session.headers['Authorization'] = "Basic {}".format(auth)
????        self.qc_url = qc_url
????        self.login()
????    def login(self):
????        r = self.api_client.post(self.qc_url.auth?? headers=self.api_client.session.headers)
????        assert(r.status_code is 200)
????    def get(self?? *args):
????        r = self.api_client.get(self.qc_url.path(*args))
????        assert (r.status_code is 200 or r.status_code is 201)
????        return r
????    def add_attachment(self?? filename?? over_ride??*args):
????        data = {
????            'filename': (""?? filename)??
????            'override-existing-attachment': (""?? over_ride)
????        }
????        files = {
????            'file': open(filename?? 'rb')
????        }
????        r = self.api_client.post(self.qc_url.path(*args)??data=data??files=files)
????        assert (r.status_code is 200 or r.status_code is 201)
????        return r
????    def query_entitys(self?? entity_name?? query_expression?? fields=None?? page_size="2000"):
????        """
????        :param entity_name: the entity to query
????        :param query_expression: the query expression
????        :param fields: the files to return in results
????        :param page_size: the result page size?? by default is 2000 which is the max value
????        :return: resturn the BeautifulSoup parsed result
????        """
????        query_url=u"%s?query={%s}&fields=%s&page-size=%s" %(entity_name??query_expression??fields??page_size)
????        r = self.get(query_url)
????        res = BeautifulSoup(r.content?? "lxml")
????        return res
????????????????????QC?????url???????
????class QCURL:
????    def __init__(self?? hostname?? domain?? project?? port='80'):
????        self.__base = u'http://{}:{}/qcbin/'.format(hostname??port)
????        self.__work = self.__base + u'rest/domains/{}/projects/{}/'.format(domain??project)
????        self.auth = self.__base + u'authentication-point/authenticate'
????        self.logout = self.__base + u'authentication-point/logout/'
????    def path(self?? *args):
????        return self.__work + '/'.join([str(arg) for arg in args])
???????е??????????QC Session??????????????????????????????????????????????????????????
????????????????????????
?????????????
???????QC????????????testset_id?????е?test-instances??????????id??test-id
????????????????????????????????????????????????????
????qc_url = QCURL(hostname?? domain?? project?? port)
????qc_session = QCSession(username?? password?? qc_url)
????qc_session.query_entitys('test-instances'?? 'contains-test-set.id[%s]' % testset_id?? "id??test-id")
????