I change your class and method names to real world equivalents to better understanding. I name a as Animal, testa as Eat, b as Human, and testb as Talk. So we have:
class Animal {      
    public void Eat() { }
}
class Human : Animal {     
    public void Talk() { }
}
Animal a1 = new Human();
Human b1 = new Animal();
OK, return to your questions.
1) You get error on second line, because every animal is NOT a human. Is it?
2) a1=new b() according to our new naming conventions, turns to a1 = new Human which means Animal a1 = new Human. So, that's correct, because human is a kind of animal. 
3) a1.testb() according to our new naming conventions, turns to a1.Talk(). Well, a1 is an animal (Animal a1), and we can not expect an animal to talk.
MORE:
Think a class is a group of attributes and behaviors. For example, we have a group named Animal that defines an Eat behavior. And another group named Human that extends Animal group and also it has its own behavior named Talk. As we know, Human has its super-group behaviors too -e.g. Eat in this example-.
When we have an instance of group Animal, we can expect it to eat. But we can not ask it to talk. It's not possible. In the other hand, every item that we choose from group Human, is actually an Animal. So we can ask him to eat.
When we have a Human instance, we can ask him to behave as a Human and as an Animal too. I mean, we can ask him to Talk and we can ask him to Eat too. Every Human can be located in human group, and in animal group. 
1) When we say Human b1 = new Animal(); it says exactly: pick up an item from Animal group - right part - and put it in Human group - left part - which is not possible. Because there are a lot of animals which are not human.
2) When we say Animal a1 = new Human: pick up an item from Human group - right part - and put it in Animal group - left part - which is easily possible. 
3) When we say a1.Talk(), we expect an Animal to talk. I mean we expect an Animal to act a Human behavior which is not possible.