范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

TDD测试驱动开发(结合需求一步步实现)

  Test-driven development
  主要是通过不断循环以下两个小步骤将需求一步步实现:在写新代码之前先写好执行失败的测试用例再写最少的代码实现使用前一步的新用例执行成功
  实际上是这种开发循环[test, code, refactor, (repeat)
  TDD 三大优点:实现的代码都是为了实现需求逻辑的写出的代码都是经过测试的,没有BUG的测试方法可以作为文档,通过测试代码很容易理解代码解决的问题
  通过下面的需求实现过程说明TDD的开发过程
  航班添加乘客业务逻辑:经济航班可以加任何类型乘客,商业航班只加VIP乘客
  移除乘客逻辑:可以任意移除普通乘客,不允许移除VIP乘客
  第一版设计
  Fight类import java.util.ArrayList; import java.util.Collections; import java.util.List;  public class Flight {      private String id;     private List passengers = new ArrayList();     private String flightType;      public Flight(String id, String flightType) {         this.id = id;         this.flightType = flightType;     }      public String getId() {         return id;     }      public List getPassengersList() {         return Collections.unmodifiableList(passengers);     }      public String getFlightType() {         return flightType;     }      public boolean addPassenger(Passenger passenger) {         switch (flightType) {             case "Economy":                 return passengers.add(passenger);             case "Business":                 if (passenger.isVip()) {                     return passengers.add(passenger);                 }                 return false;             default:                 throw new RuntimeException("Unknown type: " + flightType);         }      }      public boolean removePassenger(Passenger passenger) {         switch (flightType) {             case "Economy":                 if (!passenger.isVip()) {                     return passengers.remove(passenger);                 }                 return false;             case "Business":                 return false;             default:                 throw new RuntimeException("Unknown type: " + flightType);         }     }  }
  Passenger类public class Passenger {      private String name;     private boolean vip;      public Passenger(String name, boolean vip) {         this.name = name;         this.vip = vip;     }      public String getName() {         return name;     }      public boolean isVip() {         return vip;     }  }
  通过Airport的main方法测试public class Airport {      public static void main(String[] args) {         Flight economyFlight = new Flight("1", "Economy");         Flight businessFlight = new Flight("2", "Business");          Passenger james = new Passenger("James", true);         Passenger mike = new Passenger("Mike", false);          businessFlight.addPassenger(james);         businessFlight.removePassenger(james);         businessFlight.addPassenger(mike);         economyFlight.addPassenger(mike);          System.out.println("Business flight passengers list:");         for (Passenger passenger : businessFlight.getPassengersList()) {             System.out.println(passenger.getName());         }          System.out.println("Economy flight passengers list:");         for (Passenger passenger : economyFlight.getPassengersList()) {             System.out.println(passenger.getName());         }     } }
  改成TDD方式测试
  引入Junit5                      org.junit.jupiter             junit-jupiter-api             5.6.0             test                               org.junit.jupiter             junit-jupiter-engine             5.6.0             test              
  AirportTestimport org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test;  import static org.junit.jupiter.api.Assertions.assertEquals;  public class AirportTest {      @DisplayName("Given there is an economy flight")     @Nested     class EconomyFlightTest {          private Flight economyFlight;          @BeforeEach         void setUp() {             economyFlight = new Flight("1", "Economy");         }          @Test         public void testEconomyFlightRegularPassenger() {             Passenger mike = new Passenger("Mike", false);              assertEquals("1", economyFlight.getId());             assertEquals(true, economyFlight.addPassenger(mike));             assertEquals(1, economyFlight.getPassengersList().size());             assertEquals("Mike", economyFlight.getPassengersList().get(0).getName());              assertEquals(true, economyFlight.removePassenger(mike));             assertEquals(0, economyFlight.getPassengersList().size());         }          @Test         public void testEconomyFlightVipPassenger() {             Passenger james = new Passenger("James", true);              assertEquals("1", economyFlight.getId());             assertEquals(true, economyFlight.addPassenger(james));             assertEquals(1, economyFlight.getPassengersList().size());             assertEquals("James", economyFlight.getPassengersList().get(0).getName());              assertEquals(false, economyFlight.removePassenger(james));             assertEquals(1, economyFlight.getPassengersList().size());         }     }      @DisplayName("Given there is a business flight")     @Nested     class BusinessFlightTest {         private Flight businessFlight;          @BeforeEach         void setUp() {             businessFlight = new Flight("2", "Business");         }          @Test         public void testBusinessFlightRegularPassenger() {             Passenger mike = new Passenger("Mike", false);              assertEquals(false, businessFlight.addPassenger(mike));             assertEquals(0, businessFlight.getPassengersList().size());             assertEquals(false, businessFlight.removePassenger(mike));             assertEquals(0, businessFlight.getPassengersList().size());          }          @Test         public void testBusinessFlightVipPassenger() {             Passenger james = new Passenger("James", true);              assertEquals(true, businessFlight.addPassenger(james));             assertEquals(1, businessFlight.getPassengersList().size());             assertEquals(false, businessFlight.removePassenger(james));             assertEquals(1, businessFlight.getPassengersList().size());          }     } }
  执行测试用例后发现Airport类没使用到,可以去掉。
  Fight覆盖率小于100%,发现getFlightType没使用到,switch块的default case没覆盖,考虑重构移除未使用的代码。
  开始着手重构事宜:
  可以通过多态代替switch条件,利用多态特性(运行时而非编译时才确定实际调用具体的方法),使得开发的代码符合**开闭原则,**避免每次增加航班类型都要修改存在的类。
  第二版设计
  Flightimport java.util.ArrayList; import java.util.Collections; import java.util.List;  public abstract class Flight {      private String id;     List passengers = new ArrayList();      public Flight(String id) {         this.id = id;     }      public String getId() {         return id;     }      public List getPassengers() {         return Collections.unmodifiableList(passengers);     }      public abstract boolean addPassenger(Passenger passenger);      public abstract boolean removePassenger(Passenger passenger);  }
  EconomyFlightpublic class EconomyFlight extends Flight {      public EconomyFlight(String id) {         super(id);     }      @Override     public boolean addPassenger(Passenger passenger) {         return passengers.add(passenger);     }      @Override     public boolean removePassenger(Passenger passenger) {         if (!passenger.isVip()) {             return passengers.remove(passenger);         }         return false;     }  }
  BusinessFlightpublic class BusinessFlight extends Flight {      public BusinessFlight(String id) {         super(id);     }      @Override     public boolean addPassenger(Passenger passenger) {         if (passenger.isVip()) {             return passengers.add(passenger);         }         return false;     }      @Override     public boolean removePassenger(Passenger passenger) {         return false;     }  }
  AirportTestimport org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test;  import static org.junit.jupiter.api.Assertions.assertEquals;  public class AirportTest {      @DisplayName("Given there is an economy flight")     @Nested     class EconomyFlightTest {          private Flight economyFlight;          @BeforeEach         void setUp() {             economyFlight = new EconomyFlight("1");         }          @Test         public void testEconomyFlightRegularPassenger() {             Passenger mike = new Passenger("Mike", false);              assertEquals("1", economyFlight.getId());             assertEquals(true, economyFlight.addPassenger(mike));             assertEquals(1, economyFlight.getPassengers().size());             assertEquals("Mike", economyFlight.getPassengers().get(0).getName());              assertEquals(true, economyFlight.removePassenger(mike));             assertEquals(0, economyFlight.getPassengers().size());         }          @Test         public void testEconomyFlightVipPassenger() {             Passenger james = new Passenger("James", true);              assertEquals("1", economyFlight.getId());             assertEquals(true, economyFlight.addPassenger(james));             assertEquals(1, economyFlight.getPassengers().size());             assertEquals("James", economyFlight.getPassengers().get(0).getName());              assertEquals(false, economyFlight.removePassenger(james));             assertEquals(1, economyFlight.getPassengers().size());         }      }      @DisplayName("Given there is a business flight")     @Nested     class BusinessFlightTest {         private Flight businessFlight;          @BeforeEach         void setUp() {             businessFlight = new BusinessFlight("2");         }          @Test         public void testBusinessFlightRegularPassenger() {             Passenger mike = new Passenger("Mike", false);              assertEquals(false, businessFlight.addPassenger(mike));             assertEquals(0, businessFlight.getPassengers().size());             assertEquals(false, businessFlight.removePassenger(mike));             assertEquals(0, businessFlight.getPassengers().size());          }          @Test         public void testBusinessFlightVipPassenger() {             Passenger james = new Passenger("James", true);              assertEquals(true, businessFlight.addPassenger(james));             assertEquals(1, businessFlight.getPassengers().size());             assertEquals(false, businessFlight.removePassenger(james));             assertEquals(1, businessFlight.getPassengers().size());          }      }  }
  来了新需求,增加一种新类型航班:只允许VIP乘客乘坐,其他类型乘客不允许乘坐;可以移除任何类型的乘客。
  先实现简单的PremiumFlightpublic class PremiumFlight extends Flight {      public PremiumFlight(String id) {         super(id);     }      @Override     public boolean addPassenger(Passenger passenger) {                  return false;     }      @Override     public boolean removePassenger(Passenger passenger) {                  return false;     }  }
  AirportTestimport org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test;  import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals;  public class AirportTest {      @DisplayName("Given there is an economy flight")     @Nested     class EconomyFlightTest {          private Flight economyFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             economyFlight = new EconomyFlight("1");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you can add and remove him from an economy flight")             public void testEconomyFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and an economy flight",                         () -> assertEquals("1", economyFlight.getId()),                         () -> assertEquals(true, economyFlight.addPassenger(mike)),                         () -> assertEquals(1, economyFlight.getPassengersList().size()),                         () -> assertEquals("Mike", economyFlight.getPassengersList().get(0).getName()),                         () -> assertEquals(true, economyFlight.removePassenger(mike)),                         () -> assertEquals(0, economyFlight.getPassengersList().size())                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {             @Test             @DisplayName("Then you can add him but cannot remove him from an economy flight")             public void testEconomyFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and an economy flight",                         () -> assertEquals("1", economyFlight.getId()),                         () -> assertEquals(true, economyFlight.addPassenger(james)),                         () -> assertEquals(1, economyFlight.getPassengersList().size()),                         () -> assertEquals("James", economyFlight.getPassengersList().get(0).getName()),                         () -> assertEquals(false, economyFlight.removePassenger(james)),                         () -> assertEquals(1, economyFlight.getPassengersList().size())                 );              }         }     }      @DisplayName("Given there is a business flight")     @Nested     class BusinessFlightTest {         private Flight businessFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             businessFlight = new BusinessFlight("2");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you cannot add or remove him from a business flight")             public void testBusinessFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and a business flight",                         () -> assertEquals(false, businessFlight.addPassenger(mike)),                         () -> assertEquals(0, businessFlight.getPassengersList().size()),                         () -> assertEquals(false, businessFlight.removePassenger(mike)),                         () -> assertEquals(0, businessFlight.getPassengersList().size())                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {              @Test             @DisplayName("Then you can add him but cannot remove him from a business flight")             public void testBusinessFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and a business flight",                         () -> assertEquals(true, businessFlight.addPassenger(james)),                         () -> assertEquals(1, businessFlight.getPassengersList().size()),                         () -> assertEquals(false, businessFlight.removePassenger(james)),                         () -> assertEquals(1, businessFlight.getPassengersList().size())                 );             }         }     }      @DisplayName("Given there is a premium flight")     @Nested     class PremiumFlightTest {         private Flight premiumFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             premiumFlight = new PremiumFlight("3");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you cannot add or remove him from a premium flight")             public void testPremiumFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and a premium flight",                         () -> assertEquals(false, premiumFlight.addPassenger(mike)),                         () -> assertEquals(0, premiumFlight.getPassengersList().size()),                         () -> assertEquals(false, premiumFlight.removePassenger(mike)),                         () -> assertEquals(0, premiumFlight.getPassengersList().size())                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {              @Test             @DisplayName("Then you can add and remove him from a premium flight")             public void testPremiumFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and a premium flight",                         () -> assertEquals(true, premiumFlight.addPassenger(james)),                         () -> assertEquals(1, premiumFlight.getPassengersList().size()),                         () -> assertEquals(true, premiumFlight.removePassenger(james)),                         () -> assertEquals(0, premiumFlight.getPassengersList().size())                 );             }         }     } }
  运行测试用例发现有个测试用例失败,需要实现逻辑使测试用到通过;另外发现普通类型的乘客的测试用例是通过的,说明简单的代码已经满足业务逻辑,只需要实现VIP类型乘客的逻辑。
  实现VIP乘客的业务逻辑:public class PremiumFlight extends Flight {      public PremiumFlight(String id) {         super(id);     }      @Override     public boolean addPassenger(Passenger passenger) {         if (passenger.isVip()) {             return passengers.add(passenger);         }         return false;     }      @Override     public boolean removePassenger(Passenger passenger) {         if (passenger.isVip()) {             return passengers.remove(passenger);         }         return false;     }  }
  偶然发现程序有个BUG,同一个乘客可以重复添加,这应该不允许的,需要增加这段逻辑。TDD方式先写测试用例,使用@RepeatedTest及RepetitionInfo实现重复执行。
  AirportTestimport org.junit.jupiter.api.*;  import java.util.ArrayList;  import static org.junit.jupiter.api.Assertions.*;  public class AirportTest {      @DisplayName("Given there is an economy flight")     @Nested     class EconomyFlightTest {          private Flight economyFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             economyFlight = new EconomyFlight("1");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you can add and remove him from an economy flight")             public void testEconomyFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and an economy flight",                         () -> assertEquals("1", economyFlight.getId()),                         () -> assertEquals(true, economyFlight.addPassenger(mike)),                         () -> assertEquals(1, economyFlight.getPassengersSet().size()),                         () -> assertEquals("Mike", new ArrayList<>(economyFlight.getPassengersSet()).get(0).getName()),                         () -> assertEquals(true, economyFlight.removePassenger(mike)),                         () -> assertEquals(0, economyFlight.getPassengersSet().size())                 );             }              @DisplayName("Then you cannot add him to an economy flight more than once")             @RepeatedTest(5)             public void testEconomyFlightRegularPassengerAddedOnlyOnce(RepetitionInfo repetitionInfo) {                 for (int i = 0; i < repetitionInfo.getCurrentRepetition(); i++) {                     economyFlight.addPassenger(mike);                 }                 assertAll("Verify a regular passenger can be added to an economy flight only once",                         () -> assertEquals(1, economyFlight.getPassengersSet().size()),                         () -> assertTrue(economyFlight.getPassengersSet().contains(mike)),                         () -> assertTrue(new ArrayList<>(economyFlight.getPassengersSet()).get(0).getName().equals("Mike"))                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {             @Test             @DisplayName("Then you can add him but cannot remove him from an economy flight")             public void testEconomyFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and an economy flight",                         () -> assertEquals("1", economyFlight.getId()),                         () -> assertEquals(true, economyFlight.addPassenger(james)),                         () -> assertEquals(1, economyFlight.getPassengersSet().size()),                         () -> assertEquals("James", new ArrayList<>(economyFlight.getPassengersSet()).get(0).getName()),                         () -> assertEquals(false, economyFlight.removePassenger(james)),                         () -> assertEquals(1, economyFlight.getPassengersSet().size())                 );             }              @DisplayName("Then you cannot add him to an economy flight more than once")             @RepeatedTest(5)             public void testEconomyFlightVipPassengerAddedOnlyOnce(RepetitionInfo repetitionInfo) {                 for (int i = 0; i < repetitionInfo.getCurrentRepetition(); i++) {                     economyFlight.addPassenger(james);                 }                 assertAll("Verify a VIP passenger can be added to an economy flight only once",                         () -> assertEquals(1, economyFlight.getPassengersSet().size()),                         () -> assertTrue(economyFlight.getPassengersSet().contains(james)),                         () -> assertTrue(new ArrayList<>(economyFlight.getPassengersSet()).get(0).getName().equals("James"))                 );             }         }     }      @DisplayName("Given there is a business flight")     @Nested     class BusinessFlightTest {         private Flight businessFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             businessFlight = new BusinessFlight("2");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you cannot add or remove him from a business flight")             public void testBusinessFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and a business flight",                         () -> assertEquals(false, businessFlight.addPassenger(mike)),                         () -> assertEquals(0, businessFlight.getPassengersSet().size()),                         () -> assertEquals(false, businessFlight.removePassenger(mike)),                         () -> assertEquals(0, businessFlight.getPassengersSet().size())                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {              @Test             @DisplayName("Then you can add him but cannot remove him from a business flight")             public void testBusinessFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and a business flight",                         () -> assertEquals(true, businessFlight.addPassenger(james)),                         () -> assertEquals(1, businessFlight.getPassengersSet().size()),                         () -> assertEquals(false, businessFlight.removePassenger(james)),                         () -> assertEquals(1, businessFlight.getPassengersSet().size())                 );             }              @DisplayName("Then you cannot add him to a business flight more than once")             @RepeatedTest(5)             public void testBusinessFlightVipPassengerAddedOnlyOnce(RepetitionInfo repetitionInfo) {                 for (int i = 0; i < repetitionInfo.getCurrentRepetition(); i++) {                     businessFlight.addPassenger(james);                 }                 assertAll("Verify a VIP passenger can be added to a business flight only once",                         () -> assertEquals(1, businessFlight.getPassengersSet().size()),                         () -> assertTrue(businessFlight.getPassengersSet().contains(james)),                         () -> assertTrue(new ArrayList<>(businessFlight.getPassengersSet()).get(0).getName().equals("James"))                 );             }         }     }      @DisplayName("Given there is a premium flight")     @Nested     class PremiumFlightTest {         private Flight premiumFlight;         private Passenger mike;         private Passenger james;          @BeforeEach         void setUp() {             premiumFlight = new PremiumFlight("3");             mike = new Passenger("Mike", false);             james = new Passenger("James", true);         }          @Nested         @DisplayName("When we have a regular passenger")         class RegularPassenger {              @Test             @DisplayName("Then you cannot add or remove him from a premium flight")             public void testPremiumFlightRegularPassenger() {                 assertAll("Verify all conditions for a regular passenger and a premium flight",                         () -> assertEquals(false, premiumFlight.addPassenger(mike)),                         () -> assertEquals(0, premiumFlight.getPassengersSet().size()),                         () -> assertEquals(false, premiumFlight.removePassenger(mike)),                         () -> assertEquals(0, premiumFlight.getPassengersSet().size())                 );             }         }          @Nested         @DisplayName("When we have a VIP passenger")         class VipPassenger {              @Test             @DisplayName("Then you can add and remove him from a premium flight")             public void testPremiumFlightVipPassenger() {                 assertAll("Verify all conditions for a VIP passenger and a premium flight",                         () -> assertEquals(true, premiumFlight.addPassenger(james)),                         () -> assertEquals(1, premiumFlight.getPassengersSet().size()),                         () -> assertEquals(true, premiumFlight.removePassenger(james)),                         () -> assertEquals(0, premiumFlight.getPassengersSet().size())                 );             }              @DisplayName("Then you cannot add him to a premium flight more than once")             @RepeatedTest(5)             public void testPremiumFlightVipPassengerAddedOnlyOnce(RepetitionInfo repetitionInfo) {                 for (int i = 0; i < repetitionInfo.getCurrentRepetition(); i++) {                     premiumFlight.addPassenger(james);                 }                 assertAll("Verify a VIP passenger can be added to a premium flight only once",                         () -> assertEquals(1, premiumFlight.getPassengersSet().size()),                         () -> assertTrue(premiumFlight.getPassengersSet().contains(james)),                         () -> assertTrue(new ArrayList<>(premiumFlight.getPassengersSet()).get(0).getName().equals("James"))                 );             }         }     } } import java.util.*;  public abstract class Flight {      private String id;     Set passengers = new HashSet<>();      public Flight(String id) {         this.id = id;     }      public String getId() {         return id;     }      public Set getPassengersSet() {         return Collections.unmodifiableSet(passengers);     }      public abstract boolean addPassenger(Passenger passenger);      public abstract boolean removePassenger(Passenger passenger);  }
  TDD风格:先写测试用例再实现业务逻辑,测试覆盖率100%。

超市中,5款不起眼的零食,遇到可放心囤,成分天然又营养几乎每个人都离不开零食,但很多人买零食只顾好看,却忽视零食内在的营养。这样就导致许多零食生产商为吸引消费者,在外包装和广告上下足功夫,价格也越变越贵。逛超市的时候更是容易被花花绿绿跨年妖股,竞业达天地在线天鹅股份众生药业西安食品要注意今日的指数继续低开震荡收阴,除了连续三连阴之外,这几天的成交量也不是很健康,所以如果不能放量修复的话很有可能会来个放量大阴再次破3000,所以风险不得不防,行情随时发生转变,南京栖霞山彩枫斑斓如诗如画近日,随着气温的降低,南京栖霞山上的50多万株红叶树种正在逐渐变色。在阳光下俯瞰栖霞山,枫香红枫鸡爪槭羽毛枫等枫叶品种高低错落,呈现出浅黄鹅黄淡红粉红等色彩,仿若一幅五彩斑斓的天然秦始皇陵为什么没有皇后墓?位于陕西省西安市临潼区城东5千米,这个地方是骊山北麓,这里风景优美,林木枞枞,很早以前这里就被评为我们国家第一批的4A级景区,千古一帝秦始皇的陵墓就在这个地方,据专家考证,秦始皇陵杨坚的本名叫普六茹坚,李世民的本名叫大野世民,这是真的吗?杨坚和李世民都有自己的鲜卑姓氏,这件事确实是真的。但是,这并不意味着,老杨家和老李家就是所谓的假洋鬼子。北魏从孝文帝时代开始,就由上而下进行了汉化改革。就连皇族自身都改了姓氏,由鲜玄武门政变,李世民是被逼无奈,真的吗,不反会死吗?各位看官,说来话长,且听我慢慢道来。一,玄武门魅影626年7月2日,天还没亮。太子李建成齐王李元吉,穿过玄武门,走到临湖殿,突然觉得不对,勒马掉头。永远没人知道他到底发现什么异常,国内最大单体体育馆屋面基本完工可抵御12级大风侵袭图为航拍厦门新体育中心。中建二局安装工程有限公司厦门新体育中心项目供图中新网厦门11月10日电(李思源钟义兴)随着铝单板装饰板在预定位置安装完成,厦门新体育中心凤凰体育馆金属屋面1西地那非能天天吃吗?吃多久能有效果?治疗期间需要注意什么?西地那非属于一种口服5型磷酸二酯酶抑制剂,能够用于治疗男性功能障碍类的疾病,服用后会增强一氧化氮介导的血管扩张,尤其是会使海绵体中血管达到扩张的目的,进而增加其中的血液灌注量,以达楚汉相争项羽必败众所周知,公元前202年西楚霸王项羽拒绝了村长跨江东渡的建议而自刎乌江。那么这五年到底发生了什么事呢?为什么说楚汉相争项羽必败呢?大家跟着小编一起来看看过去五年都发生了什么事情!图清纯可人高颜值网红美女小姐姐第37期现在的网红小姐姐一个比一个貌美如花妩媚温婉,就像一首首集万千赞美于一篇的对颜值的抒情诗。天生尤物的她们统一有着含情脉脉的眸子修长白皙的玉臂玉腿,以及如玫瑰花瓣娇嫩欲滴的烈焰红唇。在搭一座心灵之桥世间万物皆有灵性,非精灵专属,生灵亦是如此,观动物世界,生灵们纵然释展缱绻相倦之情,一声呼啸即使身置远处仍能四方急奔,一地聚约,那种默契,那种齐力,那种众志成城,舍生取义,舍我其谁
冬天该怎么喝茶?喝什么茶?一次给你说明白了夏喝龙井,冬饮普洱冬季喝普洱熟茶是众多茶虫的首选,晚清时期,慈禧太后喜欢在冬季品饮普洱茶,敬茶先敬一盏普洱茶。清朝末代皇帝溥仪也曾说清宫生活习惯,夏喝龙井,冬饮普洱。就连清代的医学春节来临,阳康过后担心重阳?这9点不能大意!今年的春节似乎格外让人期待终于可以好好回家过个年,和久未相见的父母亲朋一起吃个团圆饭了。但跟往年的相聚不同,这个春节更多的人开始考虑起健康问题,毕竟好多人刚刚阳康。我们在感染新冠病卡索拉我儿子世界杯时想见姆巴佩希望回阿森纳庆祝冠军阿森纳名宿,西班牙中场桑蒂卡索拉接受了TheAthleticUK的独家专访,在专访中,他对于阿森纳的情感喷涌而出。专访的第三部分,是卡索拉谈到自己的儿子的。世界杯期间,被击败的法国81!欧足坛疯狂一夜,26年纪录刷新,11脚射门进7球神迹!昨晚今晨的欧洲足坛好戏不断,除了西超杯国家德比伦敦德比等重量级比赛,还打出了两场超级大比分!意甲中,亚特兰大主场82横扫萨勒尼塔纳,创造了意甲26年来单场进球纪录,法甲中,摩纳哥主02!澳网首日连爆冷门女单2大种子出局,中国选手淘汰欧洲猛将北京时间2023年1月16日,澳网展开正赛首日争夺,女单赛场爆出冷门,28号种子上届16强选手阿尼西莫娃02不敌科斯秋克,成为本届澳网第一位被淘汰出局的种子球员。接着,25号种子布展望巴黎奥运(三)副攻线略有不足,二传位置成隐患第一大点副攻对于眼当下的四名基本定型的国手副攻来说,他们其实或多或少都有一定的问题和优势。况且他们大多数都是9799年出生,年纪都还不算大,对于副攻来说都尚未到达真正属于自己的黄金英超3不敌布莱顿3场不胜跌至第9马奇2射1传北京时间1月14日晚23点,202223赛季英超联赛第20轮,利物浦客场挑战布莱顿。上半场,两队都没有进球下半场,马奇在开场7分钟内梅开二度,终场前又头球助攻维尔贝克锁定胜局。最终八人晋级威尔士正赛丁俊晖带领中国军团努力走出阴影北京时间1月14日晨,正在英国巴恩斯利进行的2023斯诺克威尔士公开赛先期资格赛全部结束,有多达八名中国球手晋级到了下月将在威尔士兰迪德诺进行的正赛当中,这八名球手中就包括了目前仍CBA广东惜败同曦评分无人满分一将不及格,后场双星疲态尽显CBA第二十六轮,广东男篮迎战同曦,从首节开始,广东就手感冰凉,不是一两个球员,而是全队,加上同曦防守出色,广东直到次节后段才找回状态,第三节同曦没有退缩,顶住了广东反扑,并差点把联想小新Pro超能本2023将支持140W快充,半小时内可充至66联想官方宣布,已经小新Pro超能本2023电池全面升级,能量密度充放电性能和使用寿命全面提升。目前联想官方还没有公布该款新产品的上市时间,但根据预热节奏来看,该款笔记本的发布时间应是真的?经常喝咖啡,能营养大脑神经降低心血管风险?研究来了据央视网报道,目前我国咖啡的消费者约有三亿人,咖啡不再是一种奢侈品,它逐渐走进人们的日常生活。把咖啡作为一种生活方式的打工人并不在少数,早起一杯咖啡,唤醒全新的一天下午一杯咖啡,驱