Bi-Weekly Report #3 — Tatag Aziz Prawiro

Tatag Prawiro
AdHub Team
Published in
7 min readApr 4, 2019

“Do The Simplest Thing That Could Possibly Work”

— Kent Beck

Photo by Carl Heyerdahl on Unsplash

It’s finally the third bi-week of the PPL Course. In this week’s report, I will be talking about Agile in the A-Team, Test Driven Development, and Deployment

Agile in the A-Team

Continuing what I wrote in my first report, I will be talking about how the values of agile are applied in our team. For clarity, I will be listing the manifesto and the 12 principles below with the application in our team below each point.

The Agile Manifesto

  • Individuals and interactions over processes and tools
    Application: We emphasize communication more when working rather the tech stacks itself. We first establish a good communication process (such as social media group, regular meeting) before doing anything related to the technology.
  • Working software over comprehensive documentation
    Application: We work mostly on the software itself rather than writing pages of the development plan and the like. We only use the minimum required documentation to start working, and that is the user story.
  • Customer collaboration over contract negotiation
    Application: We regularly do a meeting with the client of our application, The IDGW to ask about our current deliverables. We don’t really (or actually, never) talk about contracts and the like.
  • Responding to change over following a plan
    Application: We have a laid out plan in the beginning, but over time, there are changes that need to be made to that plan. We gladly accepted those changes and apply them to the product accordingly.

The 12 Principles of Agile

  1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
    Application: Every end of the sprint, we do a sprint review to review our product in that sprint. The client also reviews the product so that they know the current deliverable of the product and can give feedback to us.
  2. Welcome changing requirements, even late in development. Agile processes harness change for the customer’s competitive advantage.
    Application: At each sprint, we almost always finds some details that was left out during the initial plan. Those details are translated to changes and we always try to implement those changes.
  3. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.
    Application: We uses Scrum methodology, so we always deliver our working software at every end of the sprint.
  4. Business people and developers must work together daily throughout the project.
    Application: To be honest, this part is not fully done, yet. With the schedule of our client and us, it is very hard to make our meeting daily. But still, we regularly contact them via Social Media like WhatsApp to ask about the details.
  5. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.
    Application: We try to make the environment of our development team condusive. We also try to motivate each other in times of low performance and also praise each other of their hard works.
  6. The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
    Application: We regularly do a live-coding session so that we can code together face-to-face. This makes communication between different tasks very fluid.
  7. Working software is the primary measure of progress.
    Application: The progress of our product can be seen on our repository. It is the primary measure of progress. The derivative of this is like the burndown chart.
  8. Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
    Application: By using Scrum as our methodology, we pick user-stories and tasks that have the most proportional workload to our work speed. In turn, the pace of our development should be constant. However, in reality, some people might get a little bit demotivated and the pace might slow down a bit.
  9. Continuous attention to technical excellence and good design enhances agility.
    Application: Our development uses TDD and clean code, we also employ the latest technology in the back-end such as Docker, Django, etc.
  10. Simplicity — the art of maximizing the amount of work not done — is essential.
    Application: While coding, we try to use the simplest possible approach to a problem. We try not to add too much input arguments to a function.
  11. The best architectures, requirements, and designs emerge from self-organizing teams.
    Application: Our team commits in a regular meeting and we always communicate in our social media to organize our team such as when we code, when we do a meeting, and so on.
  12. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.
    Application: As we are using Scrum, we do sprint retrospective at the end of the sprint. During retrospective, we reflect on what kind of improvement we can apply to our team based on the performance of the previous sprint.

All in all, I do hope our team could become even more “agile”. And by that, I mean to be able to fully embrace the values of agile.

Test Driven Development

“I’m not a great programmer; I’m just a good programmer with great habits.”

— Kent Back

In our project, we employ the notorious Test Driven Development. TDD is not a framework, nor a language, but is actually a kind of process or a method in software development. The core of TDD is pretty simple, you make your test first and the actual code second. This might be pretty strange at first if you never used it before, but it actually has several benefits to a programmer. You might think that writing the test first is doubling the work, well, it actually is! BUT, by doing that you actually avoided the nightmare of Unlimited Debugging Works! By writing a well-written test, you would be able to avoid the triple or quadruple or even more work of debugging later.

Although, let’s be real, even with well-written test error is bound to happen, but still, TDD will minimize the error happening.

Other than that, TDD helps you to design your code. You first need to think about only the black box, what you input and what is the expected output. If the input and the output are decided, it will be easier when you write the actual function later on.

Application of TDD in The A-Team

As I said before, our team employs TDD in our project. It does help on making our application design better, here is a snippet of the test that I personally wrote.

class Google_Create_Test(TestCase):
def setUp(self):
self.client = Client()
def test_create_google_ad(self):
payload = {
'campaign': {
'customer_id': '746-601-7617',
'campaign': {
'name': 'TEST_CAMPAIGN_3',
'start_date': datetime.datetime.now().strftime('%Y%m%d'),
'end_date': (datetime.datetime.now() +
datetime.timedelta(365)).strftime('%Y%m%d'),
},
'budget': {
'amount': 100000,
'delivery_method': 'STANDARD'
}
},
'ad_group': {
'customer_id': '746-601-7617',
'campaign_id': '1738215828',
'ad_group_name': 'TEST_AD_GROUP_1'
},
'iklan': {
'ad_group_id': '67552213105',
'ad': {
'judul': 'Judul iklan',
'business_name': 'company',
'description': 'lorem ipsum description iklan',
'image_url_landscape': 'https://goo.gl/3b9Wfh',
'image_url_square': 'https://goo.gl/mtt54n',
'final_url': 'http://www.idgw.net'
},
}
}
response = create_google_ads(payload)
self.assertEqual(response.status_code, 200)

This is a test to test if the function to access the API returns the intended value. Although, I would later use stubs and mock to the actual API function since the API itself is made by Google, not by ourselves.

Deployment

During our development, we, of course, make very many changes to the code we write. It would be a real chore if we need to manually deploy our code every time we change something in order to check if our implementation works or not. In order to make our work easier, we automated our deployment process using Continuous Integration/Continuous Deployment (CI/CD) in our repository (gitlab.cs.ui.ac.id).

There are 3 stages in our product’s, AdHub’s, CI/CD which is linting, testing, and building. The 3 stages are done in that particular order.

Linting is a process to check the format or the code style of our written code. In our project, our linting process uses the PEP-8 Format and the pylint and pylint Django library.

# snippet of linting part in .gitlab-ci.ymllint:
stage: lint
script:
- pylint --load-plugins pylint_django *.py || true

Testing is the process to test our code. What it does is actually running all the test module that was made during development. Since we employ TDD, every code we write should have a test for it, and after the test is finished we will get a coverage report. Coverage report is a report about how much (in percentage) our test covers our written code.

# snippet of testing part in .gitlab-ci.yml
test:
stage: test
script:
- python manage.py runserver 8000 &
- coverage run --omit='manage.py' manage.py test
- coverage report -m

Building is the process of deploying our application on the intended platform. Since we make a web application, this process will deploy our application on the web server. We use Docker to manage our deployment process. The core principle is this, first, we create a Docker Image of our application, and then that image is pushed to the docker repository in order to be run by the web server.

In our particular project, we actually create and push 3 Docker Images. Those are development, staging, and production images. Each 3 has different purposes, development is the image of the development branch of our project, which is a branch to do “trials and errors”. Staging is the image of our staging branch, it serves as a bridge between our true production branch and our finished user-stories. Production is the branch of the final and ready-to-sell product, it is only meant to be used when the changes in the staging branch are accepted by our client and were given the green light to be deployed in the final production server.

# snippet of testing part in .gitlab-ci.yml
build_staging:
image: docker:stable
stage: build
only:
- staging
services:
- docker:dind
tags:
- build
- docker
before_script:
- docker info
script:
- docker build -t registry.docker.ppl.cs.ui.ac.id/ppla2/staging:latest .
- docker push registry.docker.ppl.cs.ui.ac.id/ppla2/staging:latest

Conclusion

Thanks for reading my report. May what I write be useful to those who read it. If you have any feedback, feel free to leave a comment in this post.

Thank you!

El Psy Congroo

--

--

Tatag Prawiro
AdHub Team

I’m just an ordinary computer science student trying to achieve the unordinary