Stephan Schwab's Personal Blog


Night Shadows

On a recent domestic flight as passenger inside China I got to see this spectacular view. The iPhone picture does not really do it justice but still I want to share it.

What I like is how the lights of the city illuminate the clouds from below.

IMG 0719

First draft of the article service

This blog post is part of a series about the development of ALE News using an approach to software development called Acceptance Test-Driven Development. For an overview please see the introductory article.

Strict separation between client and server

Unlike in the past I wanted to use a modern web application architecture. The server should not be concerned with any presentation duties. That means: no HTML will be created on the server. Instead there will be a server application exposing RESTful web services and the actual website will be rendered in the browser - being a pure client consuming the services from the server.

I want to start with a service that allows CRUD operations onto an archive for article metadata.

Preliminary description

Before going deep it makes sense to gain a rough overview of the task at hand. What follows is an overview of the planned service to access the archive for article metadata.

Feature: CRUD and list scooped articles
    Scenario: Create new article metadata
    Scenario: Read article metadata
    Scenario: Update article metadata
    Scenario: Delete article metadata
    Scenario: List article metadata

With that feature description I outlined what my service is going to do.

Creating new article metadata

With that in place I was talking to my self and came up with the following, more detailed, scenario for creating a new entry in the metadata archive.

RESTful web services use HTTP verbs to perform actions onto a resource. A good overview is available at Wikipedia. To create a new item one sends a POST request to the web service and the service should then return some ID for the newly created item.

    Scenario: Create new article metadata
        When I post the following article metadata to the article service with URI "/article"
            | Author         | Title                                            | location                                                                                                     |
            | Stephan Schwab | From competition it is a big leap to cooperation | http://www.stephan-schwab.com/china/culture/management/thoughts/2014/08/30/collaboration-or-cooperation.html |
        Then an article ID is returned
        And the article metadata has been stored in the archive

Different views about the WHAT and HOW

I would have written this scenario in a slightly different way:

    Scenario: Create new article metadata
        When I post the following article metadata to the article service
            | Author         | Title                                            | location                                                                                                     |
            | Stephan Schwab | From competition it is a big leap to cooperation | http://www.stephan-schwab.com/china/culture/management/thoughts/2014/08/30/collaboration-or-cooperation.html |
        Then an article ID is returned
        And the article metadata has been stored in the archive

The second version is more about WHAT the service does and does not give away and details about how to use the service. However, when working with a group of developers earlier this year in Berlin I learned that sometimes giving away a little hint isn't that bad. Those developers wanted to have their scenarios express how to use the service so that the scenarios can be used as some sort of user documentation for those consuming the service. I think that makes sense.

Then I created the necessary boilerplate for Cucumber JVM and provided step definitions for the first two steps of my scenario - just enough to get started.

    @When("^I post the following article metadata to the article service with URI \"(.*?)\"$")
    public void postArticle(String uri, List<ArticleMetadata> metadata) throws Throwable {
        expectedMetadata = metadata.get(0);
        actualArticleId = ClientBuilder.newClient()
                .target("http://localhost:8080/article-service").path(uri)
                .request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(expectedMetadata, MediaType.APPLICATION_JSON))
                .readEntity(ArticleId.class);
    }

    @Then("^an article ID is returned$")
    public void an_article_ID_is_returned() throws Throwable {
        assertThat(actualArticleId.getId(), is(notNullValue())) ;
    }

The Java step definition contains a number of technical details. Those are clearly about how to use the service and should definitely not be in the scenario description.

The data format used by consumer and service is JSON. In the request the client is asking for JSON data: request(MediaType.APPLICATIONJSONTYPE). It is also sending the encoded entity (the article metadata) as JSON: post(Entity.entity(expectedMetadata, MediaType.APPLICATION_JSON))

Time to write some production code

With that in place I needed to write just enough code to at least get to the Then an article ID is returned step. So I wrote this:

    @Path("article")
    public class ArticleResource {
        // todo: fake
        private static ArticleMetadata fakeArticle ;

        @POST
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_JSON)
        public ArticleId storeArticle(ArticleMetadata metadata) {
            ArticleId id = ArticleId.generate() ;
            fakeArticle = metadata ;
            fakeArticle.setId(id.getId()) ;
            return id ;
        }

    }

No storage facility needed at this point

Note that I'm using a static variable to hold the article metadata posted to the service.

Unlike other approaches, I want to focus on the behavior of the service and not spend time thinking about how the service will perform it's work on the inside. There will be a time for that later on. At the moment I feel that for the new version of ALE News I need the ability to somehow store and retrieve article metadata but there is certainly a lot more than just that. I want to explore those other things first a bit before spending time and effort on fleshing out a service that I might need to change substantially or replace with something else soon.

After all, software product development is a journey and you never know what you will discover.

More in this series

Is uncovering issues an issue?

Improvement requires that there is something that needs to be improved. If everything is just perfect or at least well enough so that everybody is happy, then there is no need to change a thing.

That sounds like commonplace wisdom. But then look a bit closer.

Improvement requires issues to exist. And it does require people willing to look for those issues.

Chinese don't like to uncover issues

My team coaching work here in China has been an interesting anthropological study so far. I try to learn as much as I can about contemporary Chinese behavior in order to tailor what I do or propose to my coachees.

In my attempts to nudge Chinese team members to find issues in their work process, collaboration with their team mates, in the interface of their workgroup/team to the rest of the organization, etc. I discovered that Chinese really dislike to uncover issues.

Some told me that the person who uncovers an issue usually will be made to fix it himself by the boss and so they rather prefer to keep quite. Apparently it is also quite likely that one will be seen as a troublemaker and therefore not considered for important work anymore.

A first hint of why that is can be obtained from this website aimed at pre-departure orientation for Chinese students. Chinese want to avoid direct confrontation, open critisism, and controversial topics. They are more concerned with maintaining harmony and to not loose their face.

Intention matters

Does uncovering issues always lead to a confrontation that one probably want to avoid?

I don't think so. I think intention matters. If I want to improve what we as a group do, then my intention is to improve - not to harm anyone.

No trust leads to confrontation

However, if the members of the group don't trust each other, then uncovering issues can easily lead to confrontation and any issue found can be used against someone who may be framed as the one who causes it or who doesn't do anything to prevent it from happening.

If I need that person's support for something important to me, then I may refrain from uncovering the issue out of fear that person will then retaliate by not supporting me anymore.

If lack of trust is an issue within your group, then maybe you want to consider the help provided by the trust artist to improve your relationships before you go out and start uncovering issues.

Improvement through experimentation

Given you have enough trust between you and the people around you, then it is probably also acceptable to fail and then you can safely perform experiments. The good thing about doing an experiment is that it's temporary. If the results are not as what you have been hoping for, then you don't have to continue. Try something else instead to see, if it works better.

The following image shows how I explain to teams improvement through experimentation and what my own role is in this scenario.

Improvement Through Experimentation

My hope is that my Chinese coachees will loosen up a bit and try some experimentation. I will encourage them to do very small experiments so that they can experience the good feeling of success, which then should help to encourage them to try some more and potentially bigger experiments.

Xi'an indoor food court and market

At the end of July and the beginning of August I had an opportunity to stroll around a bit at night in the center of Xi'an. In the basement of a department store and supermarket I discovered an indoor food court and some additional stores. Here are some impressions:

IMG 0691

IMG 0692

IMG 0693

IMG 0694

IMG 0697

IMG 0700

It can get hot in China

These guys were sitting in a restaurant waiting for their food.

IMG 0689

Bring your own container to the supermarket to buy flour or sugar

This is how in China flour, sugar and similar food items are offered for sale:

IMG 0616

Just bring your own container.

General Aviation in China

On one of my domestic flights within China I was surprised by a few articles about General Aviation in the inflight magazine.

First there was an article about a Chinese businessman who likes to fly his own helicopter.

IMG 0561

Then there was an article about an American couple who were flying around the world in their Cessna. They did multiple stops in China. Interestingly the drawing next to the map shows an aircraft that looks like a turbine powered Socata TBM or Piper Meridian. The couples' aircraft is shown in the real picture to the right with them standing in front of it. Clearly looks like a Cessna.

IMG 0562

A few pages later there was the article about Mr Hou who made his own plane, which looks like an ultra-light aircraft. It also mentions AOPA China.

IMG 0563

And eventually another article begins with a picture showing what - to me - looks like a Cirrus aircraft. The aircraft maker Cirrus Design is owned by a Chinese holding company.

IMG 0564

Apparently General Aviation is getting to China and they are picking it up. Very good :-)

From competition it is a big leap to cooperation

Collaboration and cooperation are two totally different concepts. My translators tell me that, unfortunately, in the Chinese language they basically mean the same. I've written about that before.

With the help of several translators the slides that I use for my work contain these two symbols to represent collaboration:

协同

Cooperation is presented as:

合作

But then I have seen motivational posters where 合作 was shown next to the English word collaboration together with an image of two people climbing a mountain. One was offering the other his hand to help him up.

As I've been told Chinese life is very competetive. Pupils in school compete with each other. Only the best grades will allow a student to enter one of the good Universities. And only with good grades at the University will it be possible to find a good job.

I've done a few interviews and people tell me that collaboration or cooperation at University were not a smart idea. Why help the competition.

Another additional explanation is that in China there are so many people that it were essential to be ahead of everyone else. The answer sounded like it were a question of survival.

In such a climate not to compete with coworkers but cooperate with them is a big leap.

This week I learned about another data point to understand why collaboration seems to be such an alien concept in China. In a military context 36 strategies were developed and written down in ancient China. Those 36 strategies have just one purpose: how to be smarter than the enemy and how to cheat and betray for one's own advantage. My source explained to me that in everyday business people apply the teaching of the 36 strategies.

Collaboration requires trust

Not to harm a coworker, not to interfere or sabotage other people's work makes sense in a corporate environment for workers on the same low level within a hierachical organization. After all management expects results and that is commercially usable output. There are rules and processes to make individual workers perform tasks within a value creation chain. When each worker cooperates nicely with the other workers in the chain something useable will be made.

Trust is not required to cooperate. Rules and processes make sure that nobody acts against the externally defined goal.

For collaboration trust is essential. Collaboration means two or multiple persons are working together on the same thing sharing knowledge, techniques, practices in the open. Mistakes are visible to everyone. Gaps in knowledge are visible. People learn from each other and thus may become better at something - potentially better than the others in the group.

When there is no trust, then none of that open behavior that exposes vulnerabilities makes sense. The more one shows vulnerabilities the more risk to be betrayed and taken advantage of is there. If you cannot trust the other people, then don't collaborate.

The most you can tolerate is cooperation.

Chinese developers work in silence

So far I have visited offices in Shenzhen, Xi'an, Shanghai and Beijing where thousands of software developers work.

They all work in complete silence.

Some of the offices have single person cubicles to use the existing floor space in the most efficient way to allow putting the maximum amount of desks in a given room. Others have cubicles for multiple persons where everybody faces the cubicle wall and shows his back to the others in the same space. The more nicely decorated offices, frequently also located in newer buildings, have long desks for multiple persons on either side and facing each other.

Initially I assumed that the cubicles itself were blocking communication and therefore nobody was talking to their coworker. I also observed that the cubicle workers were using extensively electronic chat tools to communicate. What especially struck me as a bit odd is that even those in the group cubicle were chatting through their computers in writing to each other. They could have simply rotated their chairs to have a face to face conversations. Their physical distance is just 2m at most.

In the more open and even in the really open workspaces the situation is the same. No conversation. The only sound one hears is typing, walking and chairs moving around.

People do get up and have group meetings in front of a whiteboard. But when they do it is one person doing the talking and others listen or answer questions from the one with the pen in hand.

Educated to listen, obey and perform tasks

Workshops that I've been doing start also with a lot of silence. People sit and watch attentively what the teacher is doing. They don't interact. At least not initially. It takes some effort to make them show some emotion and actively participate. There is some confusion on their part what they should do. It feels like workshop were an unknown concept and they seem to expect a lecture.

I've been told that the school system trains people to behave like that. At a young age Chinese learn to sit still and listen to the teacher. The teacher tells them about the subject and the pupils are expected to absorb the teacher's knowledge. At some point there will be a test and the pupils are expected to reproduce the teacher's knowledge - as accurately as possible. My sources tell me that interpretation or processing of the presented information is not expected and actively discouraged. That continues in University and then people behave as adults in a corporate context the same way.

So it is totally normal to listen to a superior, now called a leader or manager, obey his rules and perform assigned tasks.

No need to talk. No need to ask. Just do. And don't disturb the others.

The eight rules of ATDD

Recently someone at my current client was asking me about what they should do when "doing" ATDD. As the request was about a simple answer, I came up with a number of shoulds and one should not. After I wrote these eight rules down we had a good group conversation to clarify and understand what each rule means and calls for.

Intentionally I was trying to use language that is a bit vague in order to encourage thinking and discussion.

1 - You should learn the ways of your customer

Learn as much about your customer as you can.

Find out what the customer wants to do with the product you are creating. Find out how the customer usually works - without your product. Find out what he values, what preferences he has.

2 - You should learn your customer's expectations

At the very end it is the customer who either accepts or rejects your creation. As it is unlikely that you will deliver something that is completely broken, it is your customer's perception that makes or breaks the deal. Perception is connected to expectations. If you don't understand what your customer expects from your creation, then it will be difficult to make him accept it and be delighted.

3 - You should specify the behavior of your product

With a solid understanding of your customer's situation and expectations you should explain what your product will do. Share the specification of the future behavior of your product with the customer to collect further feedback to make sure that you truly understand his expectations.

4 - You should deliver expected behavior

When customer and you share the same view about the expected behavior of your product you should deliver precisely that. You may change it later, together with your customer, but it is important to deliver what you both have agreed upon as that is part of your customer's expectation and makes you trustworthy - a very important piece of entering a trustful relationship that enables close collaboration.

5 - You should continuously document actual behavior of your product

Using techniques and tools that allow you to execute the specification of the expected behavior that your product will exhibit you document that the product is indeed behaving as specified.

6 - You should create trusted blocks of code

By using a technique like TDD (Test-Driven Development) you craft the product making up your product in many tiny steps. Because you write the test before the production code you will have good coverage and you will not create any code that is not really required. That way you create blocks of code that you can trust. The better you specify what the code should do and only code the requested behavior, the more you know that your code is trustworthy.

7 - You should assemble your product using trusted blocks of code

Now that you have created all the small pieces test-first you can continue with the bigger blocks. You continue to specify behavior, but this time on a higher level, and for the implementation you use the chunks that you have created earlier.

8 - You must not verify

That is probably the biggest surprise for many people. I'm really advocating that you should not verify. Not verify anything anymore that is. Because, if you did all the things listed before, then there is nothing left that you would have to verify. You've done it already extensively and performing additional tests would be just a waste of time and money.

See a listing of all posts on this site