码迷,mamicode.com
首页 > 移动开发 > 详细

app自动化测试小成<欢迎各位大神多提宝贵意见...>

时间:2017-09-22 01:03:51      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:close   call   nta   程序   let   from   ppi   方案   psycopg2   

目录结构如下:

Test_edaike---page object设计思想 定位元素和脚本分离
Images目录---用例失败截图
case目录
  eTestfastfood.py---定位app界面元素<id,xpath>
  input开头的函数---调用sendkeys()方法
  click开头的函数---调用click()方法
  element/elements开头的函数---调用find_element/find_elements方法
test_EdaikeFastFood.py---测试用例。
  进入客位列表界面,随机选择桌位;
  判断是否开台;判断账单金额是否为0<区分加菜和查看账单操作>;
  获取bill_num,传给sqlConnect.py,核对数据库金额;
  随机使用会员价或者打折;
  随机选择付款方式;
date目录---参数化数据。暂时只做了登录的参数化
logs目录---打印日志的存储目录
pulic目录---公共文件目录
complete.py---第二次封装。click、send_kenys...
logger.py---封装logs模块,打印日志
sqlConnect.py---封装连接数据库psycopg2模块
report目录---存储生成的html报告目录
main.py---unittest执行用例,HTMLTestRunner模块生成html报告,发送邮件

附测试用例代码:

# 随机数、时间、运行cmd命令
import random, time, unittest, os, subprocess
from appium import webdriver
# 异常类
from selenium.common.exceptions import *
# 日志
from Test_edaike.public.logger import Log
# 连接数据库
from Test_edaike.public.sqlFastFood import SqL
# 元素类
from Test_edaike.case.eTestFastFood import eTestFastFood

PATH = lambda p: os.path.abspath(p)
# print(PATH)
alertTitle = (‘id‘, ‘android:id/alertTitle‘)


class FastFood(unittest.TestCase):
"""x自动化测试"""
def setUp(self):
"""初始化,appium连接设备"""
desired_caps = {
‘platformName‘: ‘Android‘,

‘deviceName‘: ‘xx‘,

‘platformVersion‘: ‘5.1.1‘,

‘appPackage‘: ‘xxx‘,

‘appActivity‘: ‘xxxx‘,

# 隐藏手机默认键盘
‘unicodeKeyboard‘: True,

‘resetKeyboard‘: True
}
# 关联appium
self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps)
self.E = eTestFastFood(self.driver)
self.username, self.password, = "", ""
self.f = open(r‘D:\TestProject\Test_edaike\date\user.txt‘, ‘r‘)
# 是否使用会员储值
self.isMember = False
# 会员储值是否需要输入密码
self.blend = False
# 是否触发营销活动
self.mark = False
# 是否估清
self.period = False
# 打折后是否金额是否为0
self.zero = False
self.bill_num = ‘‘
self.sql = SqL(‘127.0.0.1‘, ‘xxxxx‘, ‘xxxxxx‘, ‘xxxxxxx‘, ‘5432‘)

def call_function(self):
"""x点菜、下单、打折、结账操作"""
self.clickItem()
self.check_alreadyDish()
self.click_confirm_order()

# ----------------------------------登录操作-------------------------------------------

def test_function(self):
line_one = self.f.readline()
self.username, self.password = line_one.split(",")
# Log().info("用户名:%s,密码:%s" % (self.username, self.password))
print("用户名:%s,密码:%s" % (self.username, self.password))
self.login(self.username, self.password)
self.f.close()
self.call_function()

def login(self, username, password):
"""参数化用户名、密码"""
self.E.input_login_user(username)
self.E.input_login_password(password)
self.E.click_login_btn()
self.checkLoginTan()

def checkLoginTan(self):
"""判断登录弹框"""
try:
loginText = self.E.element_msg()
if loginText == ‘用户名或密码错误‘:
Log().error(‘用户名、密码错误,重试中...‘)
self.E.click_enter_btn()
line_two = self.f.readline()
if line_two:
self.username, self.password = line_two.split(",")
Log().info("用户名:%s,密码:%s" % (self.username, self.password))
self.login(self.username, self.password)
else:
self.f.close()
Log().error("没有找到正确的用户名和密码")
self.screenShot()
exit()
elif loginText == ‘收银员未签到‘:
Log().warning(‘收银员还没有签到呢,赶紧签去...‘)
self.screenShot()
exit()
elif loginText == ‘当前服务设置为快餐,该程序为e待客正餐版不可用于快餐‘:
Log().warning(‘模式不对啊,大兄弟...‘)
self.screenShot()
exit()
elif ‘未绑定收银员‘ in loginText:
Log().warning(‘没有绑定收银员?你特么在逗我玩呢...‘)
self.screenShot()
exit()
elif ‘网络链接失败‘ in loginText:
Log().warning(‘没有网...无法登录!!!‘)
self.screenShot()
exit()
else:
print(‘登录出现错误...%s‘ % loginText)
self.screenShot()
exit()
except NoSuchElementException as e:
Log().info(‘我了个草,一切正常....%s‘ % e)
except AttributeError as e:
Log().info(‘没有发生异常,正在登录^_^ %s‘ % e)

# ----------------------------------点菜操作-------------------------------------------

def clickItem(self):
"""点菜"""
self.checkTitle(‘点餐‘, ‘没有进入点餐界面诶,出错了吗?‘)
# 获取菜品小类数
itemClasses = len(self.E.elements_dish_class_item())
Log().info(‘菜品小类数量是:%s‘ % itemClasses)
# 滑动函数
self.swipeUp(itemClasses, 12, 0.1)
self.swipeDown(itemClasses, 12, 0.1)
itemClass = random.randint(0, int(itemClasses - 1))
# itemClass = 0
# 选择菜品小类
self.E.elements_dish_class_item()[itemClass].click()
# 获取菜品小类名称
className = self.E.elements_dish_name()[itemClass].text
Log().info(‘选择的菜品小类是:%s‘ % className)
itemNums = len(self.E.elements_dish_info())
# 调用滑动函数
self.swipeUp(itemNums, 12, 0.5)
Log().info(‘小类下的菜品数量是:%s‘ % itemNums)
if itemNums > 6:
itemNums = 6
# 随机点击函数
n = self.random_clicks(itemNums)
for i in n:
# 随机选择菜品
# i = 2
print(‘i:%s‘ % i)
self.E.elements_dish_info()[i].click()
self.check_itemUnit()
# 点击选好了按钮
self.E.click_go_shop_car_btn()

def check_itemUnit(self):
"""判断选择菜品样式"""
unit = self.E.elements_unit()
reason = self.E.element_reason_num()
if reason != "":
reason = reason.text
print(‘reason:%s‘ % reason)
Log().info(‘输出unit:%s‘ % unit)
if unit == ‘规格选择‘:
# 选择多规格菜品
Log().info(‘选择的菜品是多规格菜品‘)
self.moreUnitItem()
elif ‘套餐数量‘ in reason:
# 多选套餐
itemName = self.E.element_title()
Log().info(‘选择的多选套餐的名字是:%s‘ % itemName)
self.E.click_enter_btn()
self.E.click_enter_btn()
else:
Log().info(‘选择的菜品是单品或固定套餐‘)

def moreUnitItem(self):
"""选择多规格菜品"""
moreUnits = len(self.E.elements_unit_item())
# Log().info(‘选择的菜品有%s个规格‘ % moreUnits)
print(‘选择的菜品有%s个规格‘ % moreUnits)
moreUnit = random.randint(0, int(moreUnits - 1))
self.E.elements_unit_item()[moreUnit].click()
# Log().info(‘选择的规格是第%s个‘ % (moreUnit + 1))
print(‘选择的规格是第%s个‘ % (moreUnit + 1))

# ----------------------------------已点菜品界面-------------------------------------------

def check_alreadyDish(self):
"""是否进入已点菜品界面"""
alreadyDish = self.E.element_title_tv()
self.assertEqual(alreadyDish, ‘已点菜品‘, ‘没有进入已点菜品界面吗?lalala....‘)
Log().info(‘进入已点菜品界面 成功!‘)
self.bill_remark()
self.check_marketing()

def bill_remark(self):
"""选择全单备注"""
self.E.click_bill_taste()
self.E.click_enter_btn()
self.checkTitle(‘全单备注‘, ‘进入全单备注界面失败了呀!‘)
try:
remarkNums = len(self.E.elements_taste_method_select_item())
self.swipeUp(remarkNums, 18, 0.5)
r = self.random_clicks(remarkNums)
for i in r:
self.E.elements_taste_method_select_item()[i].click()
except NoSuchElementException as e:
Log().warning(‘没有分配全单备注,请分配...%s‘ % e)
self.E.click_enter_btn()

def check_marketing(self):
"""判断是否存在估清菜品"""
self.E.click_marketing()
# 估清函数
self.check_gu()
if self.period:
self.call_function()
else:
self.marketing()
if self.mark:
self.check_discount_money()

def check_gu(self):
"""检查估清提示"""
try:
textG = self.E.element_msg()
if textG == ‘点菜数量大于沽清数量‘:
self.period = True
Log().warning(‘点菜数量大于沽清数量,正在清除购物车,重新点菜。%s‘ % self.period)
self.E.click_enter_btn()
self.E.click_go_shop_car_btn()
self.E.click_clear_shop_car_btn()
self.E.click_enter_btn()
self.driver.press_keycode(4)
except NoSuchElementException as e:
print(‘所点菜品不包含估清菜品...%s‘ % e)
except AttributeError as e:
print(‘所点菜品无估清菜品...%s‘ % e)

def marketing(self):
try:
textM = self.E.element_msg()
if textM == ‘没有可用活动!‘:
Log().error(‘选择的菜品没有触发活动...‘)
self.E.click_enter_btn()
else:
print(‘选择活动出现错误...%s‘ % textM)
self.screenShot()
exit()
except AttributeError as e:
self.mark = True
Log().info(‘选择菜品已触发活动,正在选择...self.mark:%s...%s‘ % (self.mark, e))
self.checkTitle(‘营销活动‘, ‘没有进入营销活动界面qaq...‘)
marketingNums = len(self.E.elements_group_order())
self.swipeUp(marketingNums, 9, 0.5)
marketingNum = random.randint(0, int(marketingNums - 1))
# marketingNum = 0
# 随机选择活动
self.E.elements_group_order()[marketingNum].click()
marketingName = self.E.elements_group_order()[marketingNum].text
Log().info(‘随机选择的活动名称是:%s‘ % marketingName)
try:
# 活动是否存在赠送菜品
marketingItemNums = len(self.E.elements_child_order())
marketingItemNum = random.randint(0, int(marketingItemNums - 1))
# 随机选择赠送菜品
self.E.elements_child_order()[marketingItemNum].click()
marketingItemName = self.E.elements_child_order()[marketingItemNum].text
Log().info(‘赠送的菜品名称是:%s‘ % marketingItemName)
except NoSuchElementException as e:
Log().warning(‘没有复现元素,选择的活动没有赠送菜品...%s‘ % e)
except TimeoutException as e:
Log().warning(‘获取元素超时,选择的活动没有赠送菜品..%s.‘ % e)
self.E.click_config_btn()

def check_discount_money(self):
"""核对活动优惠金额"""
itemNum = len(self.E.elements_dish_name2())
print(‘已点菜品界面的菜品数量是:%s‘ % itemNum)
self.swipeUp(itemNum, 6, 0.5)
d_money = self.E.element_discount_money()
d_money = str(d_money).replace(‘-¥‘, ‘‘)
Log().info(‘参与活动的界面优惠金额是:%s‘ % d_money)
p_money = self.sql.decimal_format(
self.sql.getDate(‘select discountr_amount from pos_bill a order by a.bill_num desc limit 1;‘))
self.bill_num = self.sql.decimal_format(
self.sql.getDate(‘select bill_num from pos_bill a order by a.bill_num desc limit 1;‘))
Log().info(‘账单%s在数据库显示优惠金额是:%s‘ % (self.bill_num, p_money))
self.assertEqual(d_money, str(p_money), ‘优惠金额核对出错‘)
Log().info(‘账单%s核对优惠金额显示正确!‘ % self.bill_num)

# ----------------------------------付款、打折-------------------------------------------

def click_confirm_order(self):
""""点击结账按钮"""
self.E.click_confirm_order_btn()
self.E.input_table_code()
time.sleep(1)
self.driver.press_keycode(66)
self.E.input_table_remark()
time.sleep(1)
self.driver.press_keycode(66)
self.E.click_enter_btn()
self.check_gu()
if self.period:
self.call_function()
else:
self.payment()

def payment(self):
"""选择付款方式"""
paymentTitle = self.E.element_title()
self.assertIn(‘付款‘, paymentTitle, ‘没有进入付款页面?跑那去了?QAQ...‘)
Log().info(‘进入付款页面 成功!‘)
self.discount()
self.check_bill()
if self.zero:
self.check_pay_success()
else:
p = len(self.E.elements_payment_name())
Log().info(‘付款方式有:%s个‘ % p)
p1 = random.randint(0, int(p - 1))
# p1 = 1
# 调用滑动函数
self.swipeUp(p, 7, 0.5)
if self.isMember:
Log().info(‘选择会员储值支付方式.%s‘ % self.isMember)
self.check_payment_differ()
else:
paymentName = self.E.elements_payment_name()[p1].text
Log().info(‘选择的付款方式是%s‘ % paymentName)
if paymentName == ‘会员储值‘:
self.E.elements_payment_name()[p1].click()
self.search_card()
self.check_payment_differ()
elif paymentName == ‘会员积分‘:
self.E.elements_payment_name()[p1].click()
self.search_card()
self.check_payment_differ()
elif paymentName == ‘会员票券‘:
self.E.elements_payment_name()[p1].click()
self.search_card()
self.check_payment_differ()
elif paymentName == ‘微信支付‘:
self.E.elements_payment_name()[p1].click()
self.third_payment(‘微信‘, p1)
elif paymentName == ‘支付宝支付‘:
self.E.elements_payment_name()[p1].click()
self.third_payment(‘支付宝‘, p1)
elif paymentName == ‘人民币‘:
self.rmb_pay()
elif paymentName == ‘xxxx‘:
self.rmb_pay()
else:
Log().warning(‘付款出现异常...%s‘ % paymentName)

def discount(self):
"""打折"""
self.E.click_discount()
self.checkTitle(‘打折‘, ‘没有进入打折页面?跑那去了?QAQ...‘)
r = random.randint(0, 3)
# r = 1
Log().info(‘打折,随机数是:%d‘ % r)
if r == 0:
Log().info(‘选择折扣方式固定折扣‘)
self.E.input_discount_rate()
self.E.input_discount_money2(‘0.05‘)
self.E.click_enter_btn()
self.allowance()
self.discount_reason(‘打折成功!‘)
elif r == 1:
Log().info(‘选择折扣方式折扣方案‘)
self.E.click_special_discount()
self.discount_scheme()
self.E.input_discount_money2(‘0.05‘)
self.E.click_enter_btn()
self.allowance()
self.discount_reason(‘打折成功!‘)
elif r == 2:
Log().info(‘选择折扣方式会员优惠‘)
self.E.click_vip_discount()
self.isMember = True
self.vip_card()
elif r == 3:
Log().info(‘选择折扣方式整单折扣‘)
self.E.input_bill_discount()
self.E.input_discount_money2(‘0.05‘)
self.E.click_enter_btn()
self.allowance()
self.discount_reason(‘打折成功!‘)

def discount_scheme(self):
self.checkTitle(‘折扣方案选择‘, ‘没有进入折扣方案选择页面?跑那去了?QAQ...‘)
try:
selected_discounts = len(self.E.elements_discount_name())
selected_discount = random.randint(0, int(selected_discounts - 1))
self.E.elements_discount_name()[selected_discount].click()
self.E.click_enter_btn()
except NoSuchElementException as e:
Log().error(‘没有分配折扣方案,请分配...%s‘ % e)
self.screenShot()
exit()
except TimeoutException as e:
print(‘没有分配折扣方案,请分配...%s‘ % e)
self.screenShot()
exit()


def vip_card(self):
"""正常流程下的绑定会员卡"""
self.search_card()
self.checkTitle(‘会员消费‘, ‘没有进入会员消费页面?跑那去了?QAQ...‘)
rate = self.E.element_rate()
print(‘rate:%s‘ % rate)
if rate == ‘会员价‘:
self.E.click_enter()
self.discount_reason(‘会员价使用成功!‘)
elif ‘折‘ in rate:
self.E.click_enter()
self.check_discount_success(‘会员卡绑卡打折成功!‘)

def search_card(self):
"""查询会员卡,桌位是否已经绑定会员卡"""
self.checkTitle(‘会员检索‘, ‘没有进入会员检索页面?跑那去了?QAQ...‘)
self.E.input_phone_num()
self.E.click_search_btn()
y = self.E.is_text_in_element(alertTitle, ‘选择会员卡‘)
if y:
Log().info(‘正在选择会员卡‘)
cards = len(self.E.elements_card())
cardNum = random.randint(0, int(cards - 1))
# cardNum = 0
self.E.elements_card()[cardNum].click()
else:
Log().error(‘该会员只有一张会员卡‘)

def allowance(self):
"""折让金额大于账单金额"""
try:
allowanceText = self.E.element_msg()
if allowanceText == ‘折让金额不能大于账单金额‘:
Log().warning(‘折让金额不能大于账单金额,请重新输入折让金额...‘)
self.E.click_enter_btn()
self.E.input_discount_money2(‘0.00‘)
self.E.click_enter_btn()
except NoSuchElementException as e:
Log().info(‘allowance(),没有发现元素:%s‘ % e)
except AttributeError as e:
Log().info(‘没有出现折让金额不能大于账单金额异常%s...allowance()‘ % e)

def discount_reason(self, msg):
""""选择折扣原因 ---加异常,判断后台是否分配折扣原因"""
self.E.click_enter()
self.checkTitle(‘折扣原因‘, ‘没有进入折扣原因页面?跑那去了?QAQ...‘)
try:
discounts = len(self.E.elements_discount_name2())
discount = random.randint(0, int(discounts - 1))
self.E.elements_discount_name2()[discount].click()
self.E.click_enter_btn()
self.check_discount_success(msg)
except NoSuchElementException as e:
Log().error(‘没有分配折扣原因,请设置...%s‘ % e)
self.screenShot()
exit()

def check_discount_success(self, msg):
"""判断是否打折成功"""
text = self.E.element_msg()
if text == msg:
Log().info(msg)
self.E.click_enter_btn()
# elif text == ‘没有达到该折扣的最低账单限额‘:
# Log().warning(‘没有达到该折扣的最低账单限额!!!‘)
# self.E.click_enter_btn()
# self.driver.press_keycode(4)
# self.payment()
else:
Log().error(‘check_discount_success()出现错误...%s‘ % text)
self.screenShot()
exit()

def check_bill(self):
"""检查账单信息,判断使用的打折方式,核对界面显示金额和数据库金额"""
# 界面显示金额
payment_money = self.E.element_payment_money()
# 替换¥
payment_money = str(payment_money).replace(‘¥‘,‘‘)
Log().info(‘界面显示应收金额:%s‘ % payment_money)
money_sql = self.sql.decimal_format(
self.sql.getDate(‘select payment_amount from pos_bill order by bill_num desc limit 1‘))
self.bill_num = self.sql.decimal_format(
self.sql.getDate(‘select bill_num from pos_bill a order by a.bill_num desc limit 1;‘))
Log().info(‘数据库金额是:%s‘ % money_sql)
try:
self.assertEqual(payment_money, str(money_sql), ‘账单应收金额和数据库payment_money不一致,,,‘)
Log().info(‘账单:%s 应收金额和数据库payment_money一致‘ % self.bill_num)
except:
Log().error(‘-------------金额错误------------‘)
if payment_money == ‘0.00‘:
self.zero = True
Log().info(‘账单:%s打折后为0元账单...%s‘ % (self.bill_num, self.zero))

def check_payment_differ(self):
"""检查付款差额"""
payment_differ = self.E.element_payment_differ()
discount_money = str(payment_differ).replace(‘付款差额:¥ ‘, ‘‘).strip()
Log().info(‘付款差额:%s‘ % discount_money)
payment_money = self.E.element_payment_money()
payment_money = str(payment_money).replace(‘¥‘, ‘‘).strip()
Log().info(‘应收金额:‘ % payment_money)
if discount_money == ‘0‘:
self.E.click_payment()
self.E.input_vip_pwd()
self.driver.press_keycode(66)
self.check_pay_success()
# 付款金额和付款差额判断,如果等于0,结账;大于0,差额小于付款金额,会员卡金额不足,rmb支付,需要输入会员密码
elif discount_money != payment_money:
self.blend = True
self.rmb_pay()
else:
# 直接人民币支付,不需要输入会员密码
self.rmb_pay()

def third_payment(self, third_name, p1):
"""第三方支付"""
try:
a = 3
while a > 0:
third_paymentTitle = self.E.element_title()
if third_paymentTitle == third_name:
Log().info(‘打开%s二维码 成功!‘ % third_name)
self.driver.press_keycode(4)
self.E.click_cancel_btn()
a = a - 1
if a != 0:
self.E.elements_payment_name()[p1].click()
self.rmb_pay()
except:
third_paymentText = self.E.element_msg()
Log().error(‘%s支付出错,原因:%s‘ % (third_name, third_paymentText))
self.screenShot()
exit()

def rmb_pay(self):
"""人民币支付,需保证rmb支付在支付列表最后一个"""
Log().info(‘选择人名币支付方式‘)
p = len(self.E.elements_payment_name())
self.E.elements_payment_name()[p - 1].click()
self.driver.press_keycode(66)
if self.blend:
self.E.input_vip_pwd()
self.driver.press_keycode(66)
self.check_pay_success()

def check_pay_success(self):
"""检查是否弹出支付成功提示"""
msg = self.E.element_msg()
if msg == ‘支付成功!‘:
Log().info(‘支付成功!‘)
self.E.click_enter_btn()
self.call_function()
else:
Log().info(‘出现异常,支付失败!%s‘ % msg)
self.screenShot()
exit()

# ----------------------------------公共方法-------------------------------------------

def checkTitle(self, title, errorMsg):
"""封装check title方法"""
t = self.E.element_title()
self.assertEqual(t, title, errorMsg)
Log().info(‘进入%s页面 成功!‘ % title)

def swipeUp(self, total, number, w):
"""向上滑动函数"""
if total >= number:
t = 3000
x = self.driver.get_window_size(‘width‘)
y = self.driver.get_window_size(‘height‘)
# print(x, y)
x1 = int(x[‘width‘] * w)
y1 = int(y[‘height‘] * 0.75)
y2 = int(y[‘height‘] * 0.25)
self.driver.swipe(x1, y1, x1, y2, t)
# Log().info(‘拖拽ing,正在滑动中...‘)
print(‘拖拽ing,正在向上滑动中..‘)

def swipeDown(self, total, number, w):
"""向下滑动"""
if total >= number:
t = 3000
x = self.driver.get_window_size(‘width‘)
y = self.driver.get_window_size(‘height‘)
x1 = int(x[‘width‘] * w)
y1 = int(y[‘height‘] * 0.25)
y2 = int(y[‘height‘] * 0.75)
self.driver.swipe(x1, y1, x1, y2, t)
print(‘拖拽ing,正在向下滑动中..‘)

def screenShot(self):
"""错误截图"""
path = PATH(os.getcwd() + "/Images")
# print(path)
timestamp = time.strftime(‘%Y-%m-%d-%H-%M-%S‘, time.localtime(time.time()))
print(‘截图时间:%s‘ % timestamp)
subprocess.check_call("adb wait-for-device")
subprocess.check_call("adb shell screencap -p /data/local/tmp/tmp.png")
if not os.path.isdir(PATH(os.getcwd() + "/Images")):
os.makedirs(path)
subprocess.check_call("adb pull /data/local/tmp/tmp.png " + PATH(path + "/" + timestamp + ".png"))
subprocess.check_call("adb shell rm /data/local/tmp/tmp.png")
print("screenShot Success!!!")

def random_clicks(self, amount):
"""定义随机点击次数"""
clicks = random.randint(0, int(amount - 1))
# Log().info(‘随机点击的次数是:%s‘ % clicks)
print(‘随机点击的次数是:%s‘ % clicks)
if clicks == 0:
clicks =1
# clicks = 6
t, m = [], 0
while m < clicks:
num = random.randint(0, int(amount - 1))
t.append(num)
m += 1
return t

# ----------------------------------退出-------------------------------------------

def tearDown(self):
"""退出"""
self.sql.quitSql()
self.E.quit()

if __name__ == ‘__main__‘:
unittest.main()

app自动化刚接触没多久,自己摸索中...目前写的只是跑流程<死循环...>...希望看到的大大们留下宝贵的意见...小生在此跪谢ing...

app自动化测试小成<欢迎各位大神多提宝贵意见...>

标签:close   call   nta   程序   let   from   ppi   方案   psycopg2   

原文地址:http://www.cnblogs.com/changqing8023/p/7571786.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!