1

本篇总结将讲述一名小白从项目开始到提交的坎坷故事


部署到服务器、代码同步

第一次从头接手一个他人的半成品项目,也是第一次编写一个挂在服务器上的项目,说实话有点不知所措。试着读了读开发指南,也还是不明所以。一开始想按照之前开发论坛的方式,在本机Pycharm上进行开发和手动的功能测试,试着试着却被告知不能连接到微信,因为没有分配独立IP。只能老老实实地从配置服务器开始。

How to Set Up My First Server?

磕磕绊绊按照黄老板的教程装好了nginx和uwsgi,配置好了服务器。关注自己的测试公众号,输入help之后愉快的发现了一条回复消息,真的是激动的说不出话。

虽然是能运行了,可是在服务器上直接编写代码实在是太困难了。幸好发现了Pycharm的远程同步功能。
打开Tool > Deployment > Configuration就会出现如下的窗口。
图片描述

输入自己的用户名和密码,编辑一下右栏的Mappings。然后可以在Tool > Deployment > Options里设置一下触发同步的时机,我选择了One explicit save action,这样在使用Ctrl+S就能自动把编辑的代码同步到服务器上了!


绑定、表达式

随后开始开发我的第一个功能绑定~

简单地阅读了一下前后端接口的说明文档,发现让我实现validate_user方法。实现的方法也就是直接通过https://id.tsinghua.edu.cn进行验证,通过查看返回的url,来判断输入是不是一个匹配的学号和密码。同步代码,打开微信,输入学号密码,测试OK

随后需要我计算一个通过微信输入的四则运算表达式。简略的阅读了一下微信公众号回复消息的原理:大概是微信服务器给我们的服务器发送一条XML,经过解析和提取,提取出一个包含各个字段内容的字典msg,随后再赋给每个handler的input,调用各个handler的check方法,如果返回True则执行它的handle方法。所以我们只需要编写一个handler,接收四则运算表达式形式的微信消息,通过

result = eval(self.input['Content'])

把表达式看成一条Python语句执行,获得它的返回值就好了~


绑定的小插曲

十一还没过半,我们就发现我们的验证挂掉了:服务器不能直接访问我们清华内网的所有网页了。怎么解决呢?

软工BLOG1——使服务器可以连接到清华内网

尝试了一下Mr.Jia的openconnect + Juniper的方法,可以给我们的服务器挂上校园网的VPN来访问我们内部的网页。但是想来想去还是觉得有些不妥,一是偶尔会影响我自己使用校园网,二是服务器访问一下资源也会出错。

过了几天,我们惊异地发现外网可以访问我们的网络学堂啦~去观察了一下网络学堂POST学号和密码时的行为,把整个验证的方式改到了网络学堂上。与id的验证方法稍有不同。

        session = requests.session()
        session.post(url= alter_targeturl,data = alter_postdata)
        response = session.get(check_url)

前后端接口

之前完成绑定功能时,没有怎么读整个项目渲染显示网页的方法,导致一开始有点迷茫,不知道该从哪里下手。后来读了读开发指南和前后端接口,渐渐明白了在浏览器中输入域名按回车到显示网页之间都发生了什么。完成什么活动详情、管理微信菜单,也就是完成一个个view并把他们注册成url的处理方法。

理解了原理之后工作也就顺了很多,遵循前后端接口那篇文档中的顺序一个个完成GET和POST。这部分的工作实际上没有多少技术含量,也就是按照要求去数据库模型中查找一个或多个结果,然后转化成字典,变成JSON可以识别的返回值。可能有一点难度就是需要仔细地去考虑每个方法都该查什么,余下的就是仔细地写,慢慢排BUG吧。


微信用户功能

完成了管理员界面,终于要着手实现我们的核心功能抢票退票什么的啦。与表达式那时的模式类似,我们通过微信消息输入来甄别用户想要进行的操作,在特定的handler里实现功能,再返回合适的信息给用户。表达式时已经比较好的理解整体的工作原理,所以这部分的工作还算顺利。

可以一提的是抢票部分的逻辑:
图片描述

可以说有那么一点的复杂,不过只要仔细去想也应该没有什么问题,余下的就是代码的实现而已啦。值得注意的是,抢票不同于其他操作,这里可能会有并发而导致的错误(比如两个请求同时更新Activity表中的剩余票数remain_tickets,可能会导致计数错误),所以要在这部分对于数据库的操作中加上

with transaction.atomic():
    dosomething()

这样数据库的操作会被django.transaction交管,变成一个原子操作,不会出现并发时数据发生错误的问题。


测试

工程最后,要实现对于部分重要功能的单元测试和功能测试。配置环境时踩了不少坑:一开始在本地Python3.6+phantomjs的环境下想要运行测试,但却一直发现无法运行,找了半天发现整个项目有一条语句(datetime.now())的函数调用方式Python3.6会出错,至今也没修复。随后就理所应当的想要去用服务器的环境运行,尝试了半天,却发现在服务器上配置Phantomjs会有一些问题。最后老老实实的在本地上装Python3.5,从头开始装环境,总算是可以跑起测试=。=

仿照着讲义写起单元测试和功能测试。可能是与讲义中TDD的开发方式完全不同,我的测试基本上是一个语句覆盖的白盒测试= =,帮助我重新梳理了一下判定的思路,找到了一些BUG。不过各个部分大体还是没什么改变,有时候甚至有点纠结,到底是我的功能代码写错了?还是我的测试写错了?

实现针对抢票指令的功能测试时,需要模拟微信向服务器发送一条消息。这里一直写不对访问的url给我造成了挺大的麻烦……查了一下资料才发现可以通过StaticLiveServerTestCase中的成员live_server_url来获得测试过程中可以直接访问的本地服务器url(否则如写127.0.0.1会显示被服务器拒绝)

url = self.live_server_url + '/wechat'
response = requests.post(url= url,data= post_data)

这样才可以真正模拟向服务器发送一条消息!


部署

最后我的微信项目完工并且部署在http://139.199.25.172,这里可以操作管理员界面~
可能实际运行起来我的项目有好多BUG……我会在后续的检查中继续完善的~


AlexsaseXie
2 声望0 粉丝