Unit Test from Pain to Joy

Recently I have made an improvement in a project regarding its unit test. The improvement has a huge impact on the system in a good way. It also has a huge impact on my thinking, my philosophy about unit test, again, in a good way.

The Story

I have been working on a huge, complex codebase. It is still written with .NET 4.0, about 6 years old. Part of the system is WCF service employed CQRS style. The code has its existing unit test. And we have added more. The tests have both integration tests and mocked tests.

Integration tests, in our context, means starting with the top-most layer (presentation layer at WCF service) down to the database, and then getting data back from the database using Query Handler or Repository. In short, it is a complex testing style. And to my opinion, it is not good. I would not have done that.

Mocked tests, in our context, means mocking all the dependencies. In short, all the interfaces are mocked. Even for the domain objects, we also create proxy objects and mock their properties, methods. It turns out a big mistake.

Most of the time, we are mocking instead of testing state. There are a few problems (pain) with our approach.

First, it is hard to write. To mock dependencies, you have to know all the dependencies. Which means developers have to read the implementation code, figure out how they are interacting with each other, figure out what methods call on which interfaces. Those are not really fun. And they do not bring any real value.

Second, it is fragile. Whenever we add code or refactor a piece of code, the unit test breaks. Because the unit test assumes that a number of certain methods are there and that they are called in a specific order. Which is, in our context, not suitable.

Third, it is damn hard to write tests to verify a bug fix.

Root Cause

How did the hell on earth I end up in that situation? Everything has its own reasons. And I want to figure out mine.

I have bought this excuse for so long. And I was happy with it, unfortunately

Because the codebase is complex. The design was wrong. We do not have time to redesign it.

The fingers were pointing to the other guys, other developers. No, it was not true.

What role have I played in that mess?“, I asked. Oh, turn out I play a very big role. After reflection, here are some reasons to me not doing well on my that area.

Wrong Mindset

A long time ago, when I started knowing and writing unit tests, I was sold the thought that we have to cut the dependencies, especially the database dependency. And with the raising of mocking, the promising of TDD, I mocked (in the hope of cutting dependencies) as much as I could. It works in many scenarios. However, because I believe it is the right thing, I forget to ask right questions.

Not Ask Right Questions

I just wrote tests without asking right questions.

What am I testing here?

Kind of a stupid question, but very powerful. Depending on types of application, on the architecture, answers are different. Because of my wrong mindset, I focused on how instead of what. Answering that question allows me to analyze further, allows me to actually look at the system in a systematical way, instead of a theoretical way.

Solution

First, I decided to throw away what I thought I know about Unit Test. Here are what I want my Unit Test should be

  1. Easy to write, easy to understand from code.
  2. Resilient to refactoring. Do not have to modify unit tests when using another interface in the implementation code. In short, the tests should be there to guarantee the code correctness at maintenance phase.

While writing this post, I created a github repo, welcome to DotConnect.

What are We Testing?

Such a simple but powerful question! However, I sometimes forgot to ask. We know that we should write unit test for our code. Have we ever considered to answer that question properly? Take an example, given that we will build a simple web service (WCF) to CRUD an Account into the SQL database. What are we going to test? Each will have a different answer, thus, drive their unit test implementation.

When asking that question, the important is to remove the term Unit. I find it is a trap. When that term presents, my mind is trapped in defining what unit is. Therefore, I forget the purpose of my testing.

From my own opinion, at the abstract level, I will categorize them into 2 categories 1) Functional Test and 2) Architecture Test

Functional Test

That are tests to govern the correctness of the system. For this kind of test, we have to define clearly what is the final state.

InputOutput
The simple diagram of all processes

To implement a proper test, one must clearly define the Output. Some common outputs are 1) Database, 2) Filesystem

To define a good output, we have to define the proper scope (which comes later in this post)

Architecture Test

For some systems, architecture is important. Let’s say all the call to the Database must go through a repository. Or that the Controller (MVC application) must delegate the work to the next layer (such as Service or Command/Query Handler).

Usually, we use Mock to accomplish the testing goal. Because we do not really care about the actual implementation. We care about the sequence of calls.

What are Dependencies?

Dependencies must be listed out explicitly. At the minimum, there should be a simple diagram like this

Dependencies
High-level dependencies of the system. Each box (such as Google) is a dependency

And do not go into the detail of those dependencies. Better keep the high-level view.

What is the Scope?

Without a scope, things get messy. A proper, explicit said scope will help to define the Input and Output. I made a mistake at this question so I defined a wrong scope. I, once, defined scope at the Project level. I had a unit test for Command Handler project, which will mock the dependency to the Repository project. Then I had another unit test for Repository project. They, first, looked logical and reasonable. However, with the tested of the time, it proves I was wrong.

Once I realized it (and that is why I write this post), I defined the scope at Command Handler level only, remove the concept of Repository test. Which allows me to define the Input is the Command, and the Output is the changes in the database.

This is a game changer step for me. For years, I have been focusing on the term Unit. The problem is that it is hard to define the unit. Will it be a function, a method? Will it be a class? or Will it be an assembly? Well, I do not know. Better I just choose to forget about them.

So what do I have so far in my toolbox regarding unit test? Here they are

  1. Ask the question: What am I testing?
  2. Explicitly list all dependencies at high-level
  3. Define testing scope
My Unit Test toolbox
My Unit Test toolbox

Applicants

Back to the story, the system I have been working with is a complex system, a data-driven system. The data is back by SQL Server. From the architecture point of view, it is WCF service with CQRS architecture. When a command is executed, there are a bunch of things involved, the domain, the domain service, the external services (AD FS, payment service, …), … eventually, the data is saved into SQL Server database.

From the command side:

Q: What am I testing here?

A: Save data correctly in the database

We should not care about what domain involved, what domain service called, … They are internal implementation. And they are changed frequently. We chased the wrong rabbit hole.

From the query side:

Q: What am I testing here?

A: Get data from the database correctly.

We should not care about how data is filtered, how data is combined, … They are internal implementation. And the same reasoning goes as in Command.

In both cases, the test will give an input and verify the output. However, we still have a problem with dependencies. A big change in my mindset is that I no longer see the database as a dependency. Rather it is a part of the internal system. Why? Because it is an essential part. It can be set up locally and in CI environment. Therefore, my definition of dependency is

Dependency is external systems that we do not control. That they are hard to set up. That we do not care about their implementation. Database should NOT be one of them.

How to mock those dependencies of not using a Mocking framework? A good practice is that for every dependency, there should be a Proxy (the Proxy design pattern). The proxy implementation is injected at the runtime with the help of an IoC framework such as Windsor Container. For Unit Test, I create a fake implementation and tweak as I want.

I took me a little while to set up all those things. But it works. It gives a lot of payoffs.

Implementation Detail

[PS: This section has not finished yet. However, this post has started for a while. I think I should publish it and save the implementation detail for another post.]

To implement this kind of test, I need to interact with the database to insert and get the data regardless of the system logic. This separation is very important. To accomplish this, I use Linq To SQL.

Due to the confidential contract, I am going to create a simple demo instead of using a real application. Let’s create a simple User form MVC application.

[Code]

Having a separated assembly allows me to isolate the changes. The Linq DBContext allows me to interact with the database as I need.

All the tests have a pattern

  1. Assumption: Prepare data. This step insert the data into the database for the command to execute
  2. Arrange: Prepare the command to verify.
  3. Act: Invoke the command handler correspondent to the command. Each command has its own Command Handler.
  4. Assert: Verify the result. Use Linq To SQL to get the data from the database and verify our expectations.

Instead of repeating the steps, I create a Strategy pattern

When Mock?

There are still scenarios where the Mocking is a perfect solution. Usually, it is the top layer of the system. Let’s take MVC (WebAPI) as an example. In my opinion, the Controller should be as light-weight as possible. What a controller should do are

  1. Validate input
  2. Prepare a request (can be a Command or a Query)
  3. Dispatch the request to the next layer. If the system employees CQRS, that layer is usually a Command Handler or Query Handler.
  4. Return the result

Which steps should be mocked? The step #3. What are we testing? We test to ensure that the Controller sends correct command/query to the next layer. We test the behavior of Controllers. The mock might be a perfect fit for Architecture Test.

[Code]

What’s Next?

The implementation detail for all the stuff I write here. Now it is time to let this post out so I get something DONE.

In the Mind of a Developer

Working with a 5-6 years old system gives me a good chance to reflect on code written by other developers. When looking at an old code, even written by me, I often think “hmm what a mess! who wrote that code? what were they thinking?” That’s kind of things! The right attitude is that I should not have thought that. However, that is what’ve happened. To me, it is a good thing because I started to think of “I can do it better“.

Each codebase has its own story. This time I got a chance to look and troubleshoot another codebase. I decided to take a deeper step with questions to myself

What were the developers thinking? How would they end up in that design/decision?

The main point is for me to learn something. I am not interested in spending my time to criticise them.

The Story

Because of the contract and sensitive thoughts, I will rename and make up my terms. The system is a service that allows many systems call to log data. It has the same notion of any logging framework in .NET, such as log4net, NLog, … except this is a custom WCF service.

    public class LogCommand
    {
        public string Product { get; set; }
        public string User { get; set; }
        public DateTime CreatedAt { get; set; }
        public string LogMessage { get; set; }
    }

    public class LogEntry
    {
        public Guid ProductId { get; set; }
        public Guid UserId { get; set; }
        public DateTime CreatedAt { get; set; }
        public string LogMessage { get; set; }
    }
    public class LogCommandHandler
    {
        public void Execute(LogCommand command)
        {
            // Begin a transaction because we use NHibernate to talk with SQL Server
            var productId = CreateOrGetProduct(command);
            var userId = CreateOrGetUser(command);
            var logEntry = new LogEntry
            {
                ProductId = productId,
                UserId = userId,
                CreatedAt = command.CreatedAt,
                LogMessage = command.LogMessage
            };
            _session.Save(logEntry);
        }

        private Guid CreateOrGetProduct(LogCommand command)
        {
            // if this is a new product, create.
            // otherwise return existing product id
            return Guid.NewGuid();
        }

        private Guid CreateOrGetUser(LogCommand command)
        {
            // if this is a new user, create.
            // otherwise return existing product id
            return Guid.NewGuid();
        }
    }

There is more than above. But you get the idea. Here is the logic

  1. Get the right Product associated with the log. Insert a new Product record if a product is new.
  2. Get the right User associated with the log. Insert a new User record if a user is new.
  3. Insert a new LogEntry with the ProductId and UserId

And in the database, we have 3 tables

  1. Product: for products
  2. User: for users
  3. LogEntry: for log entries

The reason for having Product and User tables is to support searching from a WPF application (let’s call it LogViewer). At the LogViewer, users want to be able to choose Product from a dropdown. The same goes for users.

The system works as It is supposed to be …. until one day. When there are many concurrent calls to the service. It works unstable.

To cut the story short, the problem caused by the way it managed Product and User. When a production is created (but have not flushed to the database yet), it is put into a global cache to improve performance. When a next request comes in, the system will check the global cache first. Here is how the problem occurred

  1. Request 1: Create a new product, put in the global cache. But NOT commit transaction yet.
  2. Request 2: See that product in the global cache, it takes the product and assigns ProductId to the LogEntry. And it commits the transaction.
  3. The database foreign key constraint throws an exception because the ProductId has not persisted in the database yet.

Hmm? But Why?

The interesting part to me is the question I asked myself. Why? What brought the developer to that implementation?

Here is my theory.

Note: It is just me pondering my own thoughts as part of my learning practice.

Developers tend to focus on the technologies, on how to implement things. Many have been working with SQL Database for years. Thus, they have built a Relational Thinking Mindset. Let’s go back in time and try to imagine what they thought when they got the requirement.

We need to build a log service that allows us to store and search logs by product or user. A log entry will belong to a Product and be created by a User.

Oh cool! Got it. Then we will have 3 tables, one for Product, one for User, and one for Log. And we will have foreign keys from between Log and Product, between Log and User. Easy cake! Job done!

If I were him years ago, I would have done the same. What was missing? – The usage analysis.

Ok! Analysis

Move forward to now where I have years of developing, where I have a problem at hand, where I fight down the root cause. I meant I have so many information at my disposal. What questions would I ask? What concerns would I put?

What are the main operations?

  1. Write log
  2. Search log
  3. Get all products – for the search purpose
  4. Get all users – for the search purpose

What are the most frequently used operations?

  1. Write log

There is a good notion of CQRS in this service. The Write Log operation is Command, the rest are Query. Can we support queries without maintaining Product and User tables by ourselves in code? Yes, we can. SQL Server comes with the powerful concept: View.

By creating views for Product and User, the service can query on them. It gives the same result as maintaining tables.

Takeaway

What happens if we interrupt our default thinking process with

Hey! wait a minute!

That should be enough to allow us to think differently. It might help you start a questioning process.

When looking at a codebase, no matter how good/bad it is, try to reason the question

What were they thinking? How would they end up with the design?

I gain so much with this approach. So hope it works for you too.

6 Thinking Hats

Last week, I shared my 6 Thinking Hats understanding with my team. Initially, I had no clear idea of what I will talk. I just got started knowing it for a while. I love sharing my thoughts, my understanding even I have not had a strong knowledge about them. I just, well, do it. It turns out the presentation went well. The team loved the idea, loved the way I shared with them. I can feel it. At the same time, the 6 Thinking Hats idea is more visible in my mind.

Here comes the story. My wife usually mentions about the tool. She loves the idea, the principles. She has trained the tool to his co-workers. She told me to check it out. At the same time, I have read other tools, such as Mind Map, Visual Thinker, … I, well, did not check the 6 Thinking Hats. One day while driving to work, I viewed it on youtube from the author de Bono. I highly recommend you view it. And you should view it many times, at least twice. The video fits well with my driving time. By the time I got to the company, the video ended. I got the idea. I loved it.

I will write what I understand about the tool. Warning: I do not claim what I understood is correct. Each has their own understanding, own translation of the tool. If you are reading this post, please use it as a reference. If you think I misunderstood something, please write in comments. I highly appreciate. Thank you! Let’s get started.

Agenda

  1. Why? Solve problems?
  2. What?
  3. How to remember?

Why?

Why do we need 6 Thinking Hats? What kind of problems does it solve? I consider those are crucial questions.

The meeting

What were your last recent meetings? How were they going? More important, How did they end? When there is a problem, a team holds a meeting to discuss, to find a solution. They think that more heads are better than one. In terms of mathematics number, it is correct. The reality? Not so much as expected. There are many good meetings with good outcomes. I am aware of that. However, at the same time, there are many meetings with

  • Not many people involved. They are there but not there.
  • Everyone speaks their own way, their own language.
  • When an idea comes up, one person agrees, the other disagrees, … and so on.
  • People keep talking.

I wish you have good meetings

The personal thinking process

We learn many things technologies, culture, art, … How about how to think? Have we ever considered learning how to think? We often heard about *logical thinking*, *system thinking*, or *critical thinking*. Those are wonderful terms and techniques. However, looking back to the daily problem that people face, what are they? Does anything below ring any bell?

  • I do not know where to start.
  • I got stuck.
  • How do I know if I miss something?
  • ….

People, I meant many not all, are trapped in their thinking in a circle.

What is 6 Thinking Hats (6-T-H)?

Wikipedia has a full definition. For things like this, I usually have had a hard time to digest those definitions. I created my own version of understanding. At least, I can understand them in my way, thus, I can remember and use them.

6-T-H is a TOOL. It is crucial that you must see it as a TOOL. They are not some kind of magic hats that when you put on you get smarter immediately. No, it does not work that way. Just like any tool, you have to PRACTICE. Keywords are TOOLPRACTICE.

6-T-H is NOT a labeling system. There is no such a thing like: you are a black hat person, I am a white hat person or vice versa. The hats are not used to label people.

In a meeting or discussion, everyone must wear the same hat at a time.

Each hat with its color is a metaphor. The chosen color allows the metaphor to intercept the brain-default-thinking habit. The color plays the trigger role. When a color is named, a right thinking process is triggered.

Blue Hat: Managing, Controlling. When you start using 6-T-H tool, you wear it by default. Whenever you say to yourself “hey let’s try 6-T-H” you already wear the Blue Hat. Congratulations.

White Hat: Information. Just like a paper or a whiteboard. Collect the information.

Red Hat: Emotion. Express your emotion without judgment.

Black Hat: Danger, Risk, Alert. Such an important hat. You might want to ask yourself this question when wearing this hat: What can go wrong here? What am I missing here?

Yellow Hat: Value sensitive. The color reminds me of gold. Find the value, as many as possible. For everything, every situation, no matter how bad they are, there is always a good value out of it. Find it and you will see.

Green Hat: Opportunities, Possibilities. Explore all the possibilities. Sometimes, we are so focused on one thing. We are missing the many of others.

The common questions are

  1. How do I know when to wear what?
  2. What are the orders? Is there any specific order to follow?

Because there is no simple, single answer for them. They are holding people back. I would suggest that you should go with White Hat first, btw you have a Blue Hat for free when you decide to use 6-T-H. Next, you might want to use either Black, Yellow, or Green. Most of the time, I do not think that we need to use all of them.

The most important part is not about what/where/how to use them. The most important part is getting started, is to practice it. As you practice, you will define and build your own version of 6-T-H. The more you practice, the more natural it becomes to you. With time and dedicated practice, it becomes a part of your brain, of your thinking. And that is how you are thinking, that is how you are solving problems.

It is not going to work“, some might say. No, it does not. Unless you actually do it. If you are looking for ways to improve yourself, I highly suggest you try. If you think it is not going to work, or just a bullshit method, look up on the internet. You will see what people are saying about it. Still in doubt? Maybe you should try another method, maybe 6-T-H does not suit you.

How about using 6-T-H to decide if you should practice 6-T-H? That might be a cool idea.

How To Remember?

To practice anything, you have to remember them first. It must be a deep understanding, not a high school lecture. Back in the school, I was taught to learn by heart with sentences and bullet points. It works. I can do that. I can cite when someone asks. But

Back in the school, I was taught to learn by heart with sentences and bullet points. It works. I can do that. I can cite when someone asks. Problem? Think about it for a second. You are about to apply 6-T-H. Then your brain is interrupted by recalling those memories. By the time you remember them, you have lost your moment. The focus has been shifted. This remembering method is used for schools only where you learn knowledge, not skill.

Then I have had a chance to meet Mind Map. It is such a powerful tool. However, I do not feel it fits my need to remember 6-T-H. I find Mind Map is wonderful for creativity, exploring ideas, and taking notes.

Finally, I come to Visualization Thinking. I am not sure that term exists or there is a method for it. What I meant by Visualization Thinking is that I build an image of 6-T-H in my mind. The fastest way the brain can access information is by images. So instead of remembering sentences, remembering definitions, I remember images.

I built my own unique image of 6 Thinking Hats in my mind

Take an example of Yellow Hat. One might want to remember the definition in text. Or remember the keywords such as *value sensitive*. How about an image of a 9999 Golden Ring? When using an image, it allows you to explore the meanings. It is more powerful in that way.

That is just one hat. The problem is that I have to remember all hats in a connected way. Each hat is a dot. You have to connect the dot.

Here is how I built that image. I hope it can help you in some ways.

When I was listening to the video, when came to the Green Hat, the golf field came to my mind. Well, because there is a golf field in front of my condo (of course the golf field is not mine 😛 ). I took that scene, encoded, and visualized in an image.

White: A big empty paper. Imagine that I was about to paint a picture. Let’s put some information in.

Black: Draw a curly line in the middle of the paper. Black is the hell underneath. It means watch out, there is something underneath that you have not known yet.

Green: The grass on the field. Because the grass is green. There are plenty of them. They represent for opportunities, for possibilities.

Red: There is an in-love couple standing on the field. Thinking of a red face of an in-love girl. We are talking about emotion.

Yellow: Oh the man is proposing with a big golden ring. That is a good thing. Gold is value.

Blue: The sky. The sky is covering the whole picture, over the golf field. If the weather is good, the couple is still there, the grass is growing, looking good. Otherwise, things might tear apart and the picture must be re-drawn.

The image looks funny. Sometimes, it does not make sense at all. But that is the whole point. I created my own, unique image connecting everything I need to remember. I created that image weeks ago. I can access it anytime without losing a single small detail. The beautiful part of this approach is that when retrieving the image I can add more detail. It allows me to explore more.

The approach can be used in many areas of our life when we want to remember something when we are learning something. Imagination is a powerful tool. It helps us to connect the dots and put them into our long-term memory.

Final Thoughts

This is my first attempt with 6 Thinking Hats. The more I think about it, the more I like the approach. It is so simple that I can practice. The most important thing to remember is that it is a tool and has to be practiced a lot.

It is also super easy to get started. Here is how I do it. Notice that I do not apply it in every thinking or problem-solving. When I have a problem to solve, I will self-talk/self-ask:

  1. Ok, let’s apply 6 Thinking Hats to see what I can do. At that moment, I got the blue hat by default. I have started the thinking process
  2. Put on White Hat: What information do I have at hand? I write them down on paper. This is very important. If you do not write them out on a paper, you will have a problem with processing that information. Most of the time, you will be trapped in your thinking. Well, unless you are an expert.
  3. Put on Black Hat: What am I missing here? what is the real problem? Again, I write down on paper everything I can think of.
  4. Put on Green Hat: Ok Good. I have information. Let’s connect them. And find some possible outcomes – the possibilities. Sometimes, I use the Green Hat to answer the question “what is the real problem?”.
  5. Yellow Hat: What have I learn from this? This is where I extract the value from problems I have solved.

I have been working on improving my thinking pattern. Practice makes perfect.

I hope the post gives you another perspective when looking at 6 Thinking Hats. If you give it a try, I would love to hear your feedbacks on your progress. Otherwise, thank you for your time. I am very appreciated your reading time.

Setup a Full Federation Scenario with Web Application, Web Service, Windows Client, and ADFS Server Development Environment – Part 1

As a developer, we participate in many projects. In each project, there is a kind of Framework-Ready. By having framework-ready, developers just need to focus on developing business functionalities. It is a good setup, a good environment. Each person focuses on their best.

I have been working in Federation-Business-Application where the interaction is complicated, secured. And it needs a lot of environment setup. Most of the time, there is already Framework-Ready setup; I just use it.

So far so good, except I have not had enough skill in those areas. What if I have to setup a full environment locally for my sake of testing/experiencing? I felt pain just thinking about it.

5-4-3-2-1 GO! I decided to give it a GO.

Scenario

The common scenario is that there are 3 components

  1. WCF Web Service: The central service taking care of business application/logic. This service is secured and not exposed to the outside world.
  2. WPF (Windows)/Console Client: A UI application that will allow users to do their jobs internally. This client will connect to WCF service. Most of the time, users used this client has a lot of permissions.
  3. ASP.NET Web MVC Application: A public web application that allows public users to interact with the WCF Service. This application supports a subset limited of functionalities.
  4. ADFS Server: User management is done by AD FS Server.

The implementation of those applications are out of the scope, and not that interested either. The interesting part is the communication between them in a development environment.

I want to setup something like this

Scenario
General overview of components

I want to have

  1. A local AD FS server
  2. https communication between services
  3. Use Windows Identity Foundation (WIF) to manage login

Ask Google

I can explain the whole thing in words, in my mind, in the logic. I would have thought that I googled and get the job done. Reality? Google gives me so many information. All the information I need is out there. The problem is when you actually start to read them and apply in your job.

Why? Because Google can give you pieces, but you have to connect them. Google cannot help you connect the dots.

That said, I will use those piece and write the way I connect them. You might have your own way.

AD FS Server

Sounds a trivial task. Sounds like I can google it and follow the instructions. But, hell NO. Problem? Because I do not have System Administration background. Therefore, I have had a hard time understand the relationship between components. I could not draw a mental representation of them.

Googling around, I know that I have to setup things called: Domain Service (AD DS), Certificate Service (AD CS), and Federation Service (AD FS). Unfortunately, none of them knows me 🙁 I do not know them either 😛

So instead of following the instructions, I decided to make sense of them first. I have to draw a picture of them, AKA mental representation.

At the minimum, I need 3 things: Users, Certificates, and Login.

Active Directory Domain Services (AD DS)

Less than a second, I can find this useful document from Microsoft Docs.

A directory is a hierarchical structure that stores information about objects on the network. A directory service, such as Active Directory Domain Services (AD DS), provides the methods for storing directory data and making this data available to network users and administrators. For example, AD DS stores information about user accounts, such as names, passwords, phone numbers, and so on, and enables other authorized users on the same network to access this information.

Active Directory stores information about objects on the network and makes this information easy for administrators and users to find and use. Active Directory uses a structured data store as the basis for a logical, hierarchical organization of directory information.

My take:

ADDS allows me to create and manage users. That’s it! That is all I need to know.

Active Directory Certificate Services (AD CS)

Now that I have users. I need certificates to setup https communication. ADCS allows me to generate certificates that use in my lab environment. It does so many other things. However, all I need is some valid certificates to use for development purpose.

Turn it on with the instruction from Microsoft Site.

Active Directory Federation Services (AD FS)

And finally, I need to setup ADFS. There is a perfect instruction here. If you are a developer, you should check out the Microsoft Docs. At the highest abstract level (at least to my understanding), what it does is that it gives you a nice login form. It manages users who consume your service.

My ADFS Local
My AD FS Local Server. 3 services in a computer

With very little knowledge about Administration, Server, I manage to install just enough for my needs. Once I know what I have to install, it is rather easy to do. Because most of the information you need is already there, for free. The most important thing is to figure what I need, and how to make sense of them.

In my development environment, I decided

  • Everything is in one single Virtual Machine (Hyper-V from Windows)
  • Computer name: DC01. Because I might want to have other servers later on.
  • Domain: tad.local
  • AD FS: adfs.tad.local
  • Windows Server 2016 Data Center (trial version for 180 days)

The main purpose of this post is to document what I understood about them. I do not write the detail of installation processes and other problems I have had while doing it. I did that for 2 purposes

  1. Those instructions are already there, well-written, on the internet.
  2. After 6 months, when the trial is over, I have to reinstall everything again. That is a good test for my understanding. The more I do the more skill I get.

 

Next

I want to take advantage of the setup by exploring various scenarios

  1. A website uses AD FS for login.
  2. A WCF Service which serves the requests from the Website.
  3. How about a Windows Client application consumes the service? Oh yes, there is.

Again, one can easily find those topics on the internet. Nothing is new in here. I just try to write it in my own way, my own understanding.

The more I write, the better I am.

Tips to Improve English

No matter what your native language is you know how important English language is. I am a Vietnamese. I have had so many difficulties with learning English. I have studied English since I was grade 8. However, to be honest, I did not do any good before I got my first job, after my first year at the job. Even at that time, I was not that good either. I was not bad.

I can spend a whole day to give a long list of reasons why I did not do good. But just like any finding good excuses process, most of the reasons for not doing good are from outside. It is so easy to blame someone or something. Fortunately, 2 years ago, I discovered that the most important reason for not doing good was ME. In particular, here are some

  1. I did not actively learn English.
  2. I did not practice much (not mentioned that NONE)
  3. I did not look for ways to learn English.
  4. I was lazy to pronounce words.
  5. ….

Oh! they are common reasons. And they are vague and general. Which also means that they are useless. Because I cannot go anywhere with them. How do I know where to start with that list?

Fortunately, from Mr. Jim Rohn, I knew that I must start from the Fundamentals. I trust that principle. I applied it. And It works for me.

Here are some small tips that have helped me better at English every day.

Stupid Driver

I have spent lots of time on travel, either motorbike or car, from home to work and back. I decided to take advantage of those wasted hours. Instead of complaining about the road, the traffic, I practiced speaking English on my own.

The process is simple. I do not need to learn any new word. Therefore, I do not lose focus on driving. I knew that I usually forget the final sound, such as pronouncing “is”, “wish”, … Those are words I have known for years. But I have ever never got it right in speaking 🙁 While driving, I will pronounce them in the best way I can. Of course, I know how to pronounce them. The problem is not about knowing, it is about practicing. And I want to kill my laziness of moving my mouth while speaking.

The key point here is that you must speak. Do not whisper in your head. I repeat “Do not whisper in your head.” By speaking out loud, I can overcome the fear of *someone else judgment* To make it more fun, I made sentences. Many bad, careless drivers on the street, when I saw them, I spoke: “he is a stupid driver“. Well, It was not nice to say that. But who cares. I speak for myself, not in a public or pointing fingers to someone.

I have become a stupid driver since then. I have spoken to myself as a way of practicing the pronunciation. Oh yes. It works pretty well for me.

Passive Youtube

Most of my time is in front of a computer. I am a software developer. I do not have the time nor interested in taking English classes at night. Instead, I decided to take advantage of Youtube, passively.

There are a number of Authors that I want to learn, Mr. Jim Rohn is the best one. While working, instead of listening music, I listened to them. I did not pay much attention to what they were saying. I did pay attention to when I viewed the first time. Which means I already knew the content (I do not understand everything I listen to of course). But I have had an idea of what the talks are about.

For each talk that I like, I listened to them many times passively. Amazingly, I could capture their voice, their tongue, their words. Just keep listening and the brain will take care of the rest.

Active Reader

To grow in life, I need to read more books. I decided to read English books. There are many benefits of using English books. However, here is the tip that I use to improve my English. For the first 20 – 30 minutes (usually in the morning), I will read the books out loud. Usually, we read by eyes or whispering in the head.

I read the books with voice and rhythm. After 30 minutes, I feel tired, then I read as normal. One stone, two birds!

Write and Write

One of the reasons for this Blog is to practice writing. Which improves my English tremendously. Whenever possible, write in English. I have built a habit of writing everything in English, of course, as far as I can 😛

The biggest issue with writing is this: Oh man, my English is terrible. I do not know how to write. People will laugh at me. They will make fun of me

Stupid! Everyone has their own share of mistakes. No one is perfect. So who cares! I took a deep breath and moved on.

Final Thoughts

There are so many ways to learn English. But if you wait for having a right class, to have a right teacher, to have someone teach you, you will miss the train of life. Those people, those movements will not come.

Instead, look deep into your current circumstances, find a way to tweak around, and start with smallest possible actions. I am sure you will realize that you can do lots of things, that you are not in a bad situation as you thought.

Those tips work for me. They might also work for you. Who know until you give it a try.