如何用好GitHub

如何用好GitHub,并实践一些敏捷软件开发是一个很有意思的事情.我们可以在上面做很多事情,从测试到CI,再到自动部署.

敏捷软件开发

显然我是在扯淡,这和敏捷软件开发没有什么关系。不过我也不知道瀑布流是怎样的。说说我所知道的一个项目的组成吧:

  • 看板式管理应用程序(如trello,简单地说就是管理软件功能)
  • CI(持续集成)
  • 测试覆盖率
  • 代码质量(code smell)

对于一个不是远程的团队(如只有一个人的项目) 来说,Trello、Jenkin、Jira不是必需的:

你存在,我深深的脑海里

当只有一个人的时候,你只需要明确知道自己想要什么就够了。我们还需要的是CI、测试,以来提升代码的质量。

测试

通常我们都会找Document,如果没有的话,你会找什么?看源代码,还是看测试?

  1. it("specifying response when you need it", function (done) {
  2. var doneFn = jasmine.createSpy("success");
  3. lettuce.get('/some/cool/url', function (result) {
  4. expect(result).toEqual("awesome response");
  5. done();
  6. });
  7. expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
  8. expect(doneFn).not.toHaveBeenCalled();
  9. jasmine.Ajax.requests.mostRecent().respondWith({
  10. "status": 200,
  11. "contentType": 'text/plain',
  12. "responseText": 'awesome response'
  13. });
  14. });

代码来源: https://github.com/phodal/lettuce

上面的测试用例,清清楚楚地写明了用法,虽然写得有点扯。

等等,测试是用来干什么的。那么,先说说我为什么会想去写测试吧:

  • 我不希望每次做完一个个新功能的时候,再手动地去测试一个个功能。(自动化测试)
  • 我不希望在重构的时候发现破坏了原来的功能,而我还一无所知。
  • 我不敢push代码,因为我没有把握。

虽然,我不是TDD的死忠,测试的目的是保证功能正常,TDD没法让我们写出质量更高的代码。但是有时TDD是不错的,可以让我们写出逻辑更简单地代码。

也许你已经知道了SeleniumJasmineCucumber等等的框架,看到过类似于下面的测试

  1. Ajax
  2. specifying response when you need it
  3. specifying html when you need it
  4. should be post to some where
  5. Class
  6. respects instanceof
  7. inherits methods (also super)
  8. extend methods
  9. Effect
  10. should be able fadein elements
  11. should be able fadeout elements

代码来源: https://github.com/phodal/lettuce

看上去似乎每个测试都很小,不过补完每一个测试之后我们就得到了测试覆盖率

File Statements Branches Functions Lines
lettuce.js 98.58% (209 / 212) 82.98%(78 / 94) 100.00% (54 / 54) 98.58% (209 / 212)

本地测试都通过了,于是我们添加了Travis-CI来跑我们的测试

CI

虽然node.js不算是一门语言,但是因为我们用的node,下面的是一个简单的.travis.yml示例:

  1. language: node_js
  2. node_js:
  3. - "0.10"
  4. notifications:
  5. email: false
  6. before_install: npm install -g grunt-cli
  7. install: npm install
  8. after_success: CODECLIMATE_REPO_TOKEN=321480822fc37deb0de70a11931b4cb6a2a3cc411680e8f4569936ac8ffbb0ab codeclimate < coverage/lcov.info

代码来源: https://github.com/phodal/lettuce

我们把这些集成到README.md之后,就有了之前那张图。

CI对于一个开发者在不同城市开发同一项目上来说是很重要的,这意味着当你添加的部分功能有测试覆盖的时候,项目代码会更加强壮。

代码质量

jslint这类的工具,只能保证代码在语法上是正确的,但是不能保证你写了一堆bad smell的代码。

  • 重复代码
  • 过长的函数
  • 等等

Code Climate是一个与github集成的工具,我们不仅仅可以看到测试覆盖率,还有代码质量。

先看看上面的ajax类:

  1. Lettuce.get = function (url, callback) {
  2. Lettuce.send(url, 'GET', callback);
  3. };
  4. Lettuce.send = function (url, method, callback, data) {
  5. data = data || null;
  6. var request = new XMLHttpRequest();
  7. if (callback instanceof Function) {
  8. request.onreadystatechange = function () {
  9. if (request.readyState === 4 && (request.status === 200 || request.status === 0)) {
  10. callback(request.responseText);
  11. }
  12. };
  13. }
  14. request.open(method, url, true);
  15. if (data instanceof Object) {
  16. data = JSON.stringify(data);
  17. request.setRequestHeader('Content-Type', 'application/json');
  18. }
  19. request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  20. request.send(data);
  21. };

代码来源: https://github.com/phodal/lettuce

Code Climate在出现了一堆问题

  • Missing “use strict” statement. (Line 2)
  • Missing “use strict” statement. (Line 14)
  • ‘Lettuce’ is not defined. (Line 5)

而这些都是小问题啦,有时可能会有

  • Similar code found in two :expression_statement nodes (mass = 86)

这就意味着我们可以对上面的代码进行重构,他们是重复的代码。